修复框架和商城问题
增加代码生成器
This commit is contained in:
wangchen147 2024-11-16 14:22:36 +08:00
parent 2fb0a88fdd
commit d529ebae2b
1503 changed files with 15685 additions and 9050 deletions

View File

@ -54,6 +54,7 @@ declare module '@vue/runtime-core' {
ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']

View File

@ -137,7 +137,7 @@ export function deleteGenerateTable(id: number) {
* @returns
*/
export function generateCreate(params: Record<string, any>) {
return request.post(`generator/download`, params)
return request.post('/generator/download', params)
}
/**

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -7,7 +7,7 @@
"menuTypeButton": "按钮",
"menuDeleteTips": "删除菜单会删除当前菜单以及该菜单下所有子菜单,是否确认删除?",
"initializeMenu":"重置菜单",
"initializeMenuTipsOne":"重置菜单会将应用或插件的dict目录下的菜单配置文件中菜单配置更新到数据库一般用做开发者修改了dict菜单配置文件后,同步到数据库操作。",
"initializeMenuTipsOne":"重置菜单会将应用或插件的menu目录下的菜单配置文件中菜单配置更新到数据库一般用做开发者修改了menu菜单配置文件后,同步到数据库操作。",
"initializeMenuTipsTwo":"如果用户手动调整过以下菜单项,通常允许进行本项操作,操作会重置为原始菜单。 请谨慎使用!",
"addMenu": "添加菜单",
"updateMenu": "编辑菜单",

View File

@ -47,5 +47,15 @@
"polygon": "多边形",
"angle": "旋转角度",
"nickName": "昵称",
"needLoginTips": "前台需要登录才会展示"
"needLoginTips": "前台需要登录才会展示",
"horizontalAlignment": "水平对齐方式",
"verticalAlignment": "垂直对齐方式",
"AlignTips": "当设置文本水平对齐方式时,其内容也会随之改变",
"lineHeight": "行高",
"textAlign": "文字居中方式",
"space": "字间距",
"weight": "文字加粗",
"imgShape": "图片形状"
}

View File

@ -17,33 +17,24 @@
</div>
<img src="@/app/assets/images/tools/addon_develop.png" class="w-[256px] h-[128px]" />
</div>
<!-- <div class="w-[256px] tools-item-shadow m-[20px] !mr-[0px] !mt-[0px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/admin/tools/code')">-->
<!-- <div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col bg-[var(&#45;&#45;el-bg-color)]">-->
<!-- <span class="text-[16px] font-bold">代码生成</span>-->
<!-- <div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">-->
<!-- 代码生成-->
<!-- </div>-->
<!-- </div>-->
<!-- <img src="@/app/assets/images/tools/code.png" class="w-[256px] h-[128px]" />-->
<!-- </div>-->
<!-- <div class="w-[256px] tools-item-shadow m-[20px] !mr-[0px] !mt-[0px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/admin/tools/list')">-->
<!-- <div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col bg-[var(&#45;&#45;el-bg-color)]">-->
<!-- <span class="text-[16px] font-bold">数据字典</span>-->
<!-- <div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">-->
<!-- 数据字典-->
<!-- </div>-->
<!-- </div>-->
<!-- <img src="@/app/assets/images/tools/sys_dict_list.png" class="w-[256px] h-[128px]" />-->
<!-- </div>-->
<!-- <div class="w-[256px] tools-item-shadow m-[20px] !mr-[0px] !mt-[0px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/admin/tools/detection')">-->
<!-- <div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col bg-[var(&#45;&#45;el-bg-color)]">-->
<!-- <span class="text-[16px] font-bold">环境监测</span>-->
<!-- <div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">-->
<!-- 环境监测-->
<!-- </div>-->
<!-- </div>-->
<!-- <img src="@/app/assets/images/tools/tools_check_environment.png" class="w-[256px] h-[128px] cursor-pointer" />-->
<!-- </div>-->
<div class="w-[256px] tools-item-shadow m-[20px] !mr-[0px] !mt-[0px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/admin/tools/code')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col bg-[var(--el-bg-color)]">
<span class="text-[16px] font-bold">代码生成</span>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
代码生成
</div>
</div>
<img src="@/app/assets/images/tools/code.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] tools-item-shadow m-[20px] !mr-[0px] !mt-[0px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/admin/tools/list')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col bg-[var(--el-bg-color)]">
<span class="text-[16px] font-bold">数据字典</span>
<div class="text-[13px] text-[#6D7278] leading-[18px] mt-[8px] truncate">
数据字典
</div>
</div>
<img src="@/app/assets/images/tools/sys_dict_list.png" class="w-[256px] h-[128px]" />
</div>
<div class="w-[256px] tools-item-shadow m-[20px] !mr-[0px] !mt-[0px] rounded-[8px] flex flex-col cursor-pointer leading-[1]" @click="toLink('/admin/tools/schedule')">
<div class="flex-1 pt-[18px] pb-[14px] px-[24px] flex flex-col bg-[var(--el-bg-color)]">
<span class="text-[16px] font-bold">计划任务</span>

View File

@ -7,8 +7,15 @@
</div>
<!-- 组件公共属性 -->
<slot name="common"></slot>
<slot name="common"></slot>
<el-form label-width="80px" class="px-[10px]">
<el-form-item :label="t('imgShape')">
<div class="flex items-center">
<div class="bg-[#DFDFDF] cursor-pointer w-[50px] h-[50px] border-solid border-[1px] border-transparent rounded-[50%]" :class="{'border-[var(--el-color-primary)]': posterStore.editComponent.shape == 'circle'}" @click="imgShapeChangeFn('circle')"></div>
<div class="bg-[#DFDFDF] cursor-pointer w-[50px] h-[50px] ml-[25px] border-solid border-[1px] border-transparent" :class="{'border-[var(--el-color-primary)]': posterStore.editComponent.shape == 'normal'}" @click="imgShapeChangeFn('normal')"></div>
</div>
</el-form-item>
</el-form>
</div>
</template>
@ -19,6 +26,11 @@ import usePosterStore from '@/stores/modules/poster'
const posterStore = usePosterStore()
//
const imgShapeChangeFn = (data)=>{
posterStore.editComponent.shape = data;
}
defineExpose({})
</script>

View File

@ -18,7 +18,7 @@
<div class="text-sm text-gray-400 mt-[10px]">{{ t('bgUrlTips') }}</div>
</el-form-item>
<el-form-item :label="t('bgColor')" v-show="posterStore.global.bgType == 'color'">
<el-color-picker v-model="posterStore.editComponent.bgColor" show-alpha :predefine="posterStore.predefineColors" />
<el-color-picker v-model="posterStore.editComponent.bgColor" :predefine="posterStore.predefineColors" />
</el-form-item>
<el-form-item :label="t('statusLabel')" class="display-block">
<el-switch v-model="posterStore.status" :active-value="1" :inactive-value="0"/>

View File

@ -1,6 +1,6 @@
<template>
<div class="pointer-events-none max-w-[360px]" :style="componentStyle">
<img src="@/app/assets/images/default_headimg.png" class="w-full h-full" />
<div class="pointer-events-none max-w-[720px]" :style="componentStyle">
<img src="@/app/assets/images/default_headimg_square.jpg" class="w-full h-full" />
</div>
</template>
@ -22,6 +22,9 @@ const data = computed(()=> {
const componentStyle = computed(()=> {
var style = '';
style += `width: ${prop.value.width}px;`;
if(prop.value.shape == 'circle'){
style += `border-radius: 50%; overflow: hidden;`;
}
return style;
})

View File

@ -1,5 +1,5 @@
<template>
<div class="pointer-events-none max-w-[360px]" :style="componentStyle">
<div class="pointer-events-none max-w-[720px]" :style="componentStyle">
<img v-if="data.value" :src="img(data.value)" class="w-full h-full" />
<img v-else :src="img('static/resource/images/diy/crack_figure.png')" class="w-full h-full" />
</div>

View File

@ -4,6 +4,9 @@
<script lang="ts" setup>
import { ref,computed } from 'vue'
import usePosterStore from '@/stores/modules/poster'
const posterStore = usePosterStore()
const prop = defineProps({
value: {
@ -18,7 +21,22 @@ const data = computed(()=> {
const componentStyle = computed(()=> {
var style = '';
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};`;
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};line-height: ${prop.value.lineHeight + prop.value.fontSize}px;`;
if(prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right'){
style += `text-align: ${prop.value.x};`;
}
if(prop.value.weight){
style += `font-weight: bold;`;
}
if(!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf'){
style += `font-family: poster_default_font;`;
}
let box: any = document.getElementById(prop.value.id)
if (box) {
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`;
}else{
style += `width:${prop.value.width}px;height:${prop.value.height}px;`;
}
return style;
})

View File

@ -1,5 +1,5 @@
<template>
<div class="pointer-events-none max-w-[360px]" :style="componentStyle">
<div class="pointer-events-none max-w-[720px]" :style="componentStyle">
<img :src="img('static/resource/images/diy/qrcode.png')" class="w-full h-full" />
</div>
</template>

View File

@ -4,6 +4,9 @@
<script lang="ts" setup>
import { ref,computed } from 'vue'
import usePosterStore from '@/stores/modules/poster'
const posterStore = usePosterStore()
const prop = defineProps({
value: {
@ -18,10 +21,21 @@ const data = computed(()=> {
const componentStyle = computed(()=> {
var style = '';
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};`;
style += `font-size: ${prop.value.fontSize}px;color: ${prop.value.fontColor};line-height: ${prop.value.lineHeight + prop.value.fontSize}px;`;
if(prop.value.x == 'left' || prop.value.x == 'center' || prop.value.x == 'right'){
style += `text-align: ${prop.value.x};`;
}
if(prop.value.weight){
style += `font-weight: bold;`;
}
if(!prop.value.fontFamily || prop.value.fontFamily == 'static/font/SourceHanSansCN-Regular.ttf'){
style += `font-family: poster_default_font;`;
}
let box: any = document.getElementById(prop.value.id)
if (box) {
style += `width:${box.offsetWidth}px;height:${box.offsetHeight}px;`;
}else{
style += `width:${prop.value.width}px;height:${prop.value.height}px;`;
}
return style;
})

View File

@ -57,7 +57,7 @@
<div class="title-wrap text-center text-[14px]">{{ posterStore.name }}</div>
</div>
</div>
<div class="preview-block relative">
<div class="preview-block relative max-h-[640px]">
<ul class="quick-action absolute text-center -right-[70px] top-[20px] w-[42px] rounded shadow-md">
<el-tooltip effect="light" :content="t('moveUpComponentZIndex')" placement="right">
<icon name="iconfont iconjiantoushang" size="20px" class="block cursor-pointer leading-[40px]" @click="posterStore.moveUpComponent" />
@ -78,8 +78,8 @@
<!-- 组件预览渲染区域 -->
<div class="preview-iframe" :style="posterStore.getGlobalStyle()" @click="posterStore.changeCurrentIndex(-99)">
<div class="item-wrap area-box select-none max-w-[360px] cursor-move" v-for="(item,index) in posterStore.value" :id="item.id" :key="item.id"
:style="{ top: item.y + 'px', left: item.x + 'px', zIndex: item.zIndex, transform : 'rotate(' + item.angle + 'deg)' }"
<div class="item-wrap area-box select-none max-w-[720px] cursor-move" v-for="(item,index) in posterStore.value" :id="item.id" :key="item.id"
:style="previewIframeStyle(item)"
:class="{ 'selected' : posterStore.currentIndex == index }"
@mousedown="posterStore.mouseDown($event,item.id,index)"
@click.stop="posterStore.changeCurrentIndex(index,item)"
@ -106,7 +106,7 @@
<el-card class="box-card" shadow="never">
<template #header>
<div class="card-header flex justify-between items-center">
<span class="title flex-1">{{ posterStore.currentIndex == -99 ? t('posterSet') : posterStore.editComponent.componentTitle }}</span>
<span class="title flex-1">{{ posterStore.currentIndex == -99 ? t('posterSet') : posterStore.editComponent?.componentTitle }}</span>
</div>
</template>
@ -116,7 +116,7 @@
<template #common>
<div class="edit-attr-item-wrap">
<h3 class="mb-[10px]">{{ t('componentStyleTitle') }}</h3>
<el-form label-width="80px" class="px-[10px]">
<el-form label-width="100px" class="px-[10px]">
<!-- 角度旋转这里根据类型展示 文本图片绘画的编辑属性 -->
@ -124,22 +124,30 @@
<span>{{ posterStore.editComponent.zIndex }}</span>
</el-form-item>
<el-form-item :label="t('coordinate')">
<!-- <el-form-item :label="t('coordinate')">
<el-slider v-model="posterStore.editComponent.x" show-input size="small" class="ml-[10px]" :min="0" :max="posterStore.getMaxX()" />
<div class="my-[10px]"></div>
<el-slider v-model="posterStore.editComponent.y" show-input size="small" class="ml-[10px]" :min="0" :max="posterStore.getMaxY()" />
</el-form-item>
<div class="ml-[92px] mb-[18px] text-sm text-gray-400">{{ t('coordinateTips') }}</div>
<div class="ml-[92px] mb-[18px] text-sm text-gray-400">{{ t('coordinateTips') }}</div> -->
<!-- 文本 -->
<template v-if="posterStore.editComponent.type == 'text'">
<el-form-item :label="t('textFontSize')">
<el-slider v-model="posterStore.editComponent.fontSize" show-input size="small" class="ml-[10px]" :min="14" :max="36" />
<el-slider v-model="posterStore.editComponent.fontSize" show-input size="small" class="ml-[10px]" :min="14" :max="50" />
</el-form-item>
<el-form-item :label="t('textColor')">
<el-color-picker v-model="posterStore.editComponent.fontColor" />
</el-form-item>
<el-form-item :label="t('weight')">
<el-switch v-model="posterStore.editComponent.weight" />
</el-form-item>
<!-- <el-form-item :label="t('space')">
<el-slider v-model="posterStore.editComponent.space" show-input size="small" class="ml-[10px]" :min="0" :max="20" />
</el-form-item> -->
<el-form-item :label="t('lineHeight')">
<el-slider v-model="posterStore.editComponent.lineHeight" show-input size="small" class="ml-[10px]" :min="0" :max="50" />
</el-form-item>
</template>
<!-- 图片 -->
@ -162,6 +170,30 @@
</el-form-item>
</template>
<!-- 对齐方式 -->
<template v-if="posterStore.editComponent.type != 'draw' && posterStore.editComponent.type != 'image' && posterStore.editComponent.type != 'qrcode'">
<el-form-item :label="t('horizontalAlignment')">
<ul class="flex items-center">
<template v-for="(item,i) in xAlignList">
<li :class="['w-[50px] h-[32px] flex items-center justify-center border-solid border-[1px] border-[#eee] cursor-pointer', {'border-r-transparent': xAlignList.length != (i+1)}, (item.className == posterStore.editComponent.x) ? '!border-[var(--el-color-primary)]' : '' ]" @click="alignChangeFn('x',item)">
<span :class="['iconfont !text-[20px]', item.src]" :title="item.name"></span>
</li>
</template>
</ul>
<div class="text-sm mt-[10px] leading-[1.4] text-gray-400">{{ t('AlignTips') }}</div>
</el-form-item>
<el-form-item :label="t('verticalAlignment')">
<ul class="flex items-center">
<template v-for="(item,i) in yAlignList">
<li :class="['w-[50px] h-[32px] flex items-center justify-center border-solid border-[1px] border-[#eee] cursor-pointer', {'border-r-transparent': yAlignList.length != (i+1)}, (item.className == posterStore.editComponent.y) ? '!border-[var(--el-color-primary)]' : '' ]" @click="alignChangeFn('y',item)">
<span :class="['iconfont !text-[20px]', item.src]" :title="item.name"></span>
</li>
</template>
</ul>
</el-form-item>
</template>
<!-- <el-form-item :label="t('旋转角度')">-->
<!-- <el-slider v-model="posterStore.editComponent.angle" show-input size="small" class="ml-[10px]" :min="0" :max="360" />-->
<!-- </el-form-item>-->
@ -209,10 +241,12 @@ const posterStore = usePosterStore()
const route = useRoute()
const router = useRouter()
route.query.id = route.query.id || 0
route.query.type = route.query.type || '' //
route.query.name = route.query.name || ''
route.query.back = route.query.back || '/site/poster/list'
if(route && route.query){
route.query.id = route.query.id || 0
route.query.type = route.query.type || '' //
route.query.name = route.query.name || ''
route.query.back = route.query.back || '/site/poster/list'
}
const backPath:any = route.query.back
const template = ref('');
@ -226,6 +260,90 @@ const activeNames = ref(componentType)
const handleChange = (val: string[]) => {
}
const previewIframeStyle = (data: any)=>{
let style: any = {
transform: '',
zIndex: '',
top: '',
left: '',
right: '',
bottom: ''
};
style.transform = `rotate(${data.angle}deg)`;
style.zIndex = `${data.zIndex}`;
switch(data.y) {
case 'top':
style.top = 0;
break;
case 'center':
style.top = '50%';
style.transform = style.transform + ' translateY(-50%)';
break;
case 'bottom':
style.bottom = 0;
break;
default:
style.top = data.y + 'px';
}
switch(data.x) {
case 'left':
style.left = 0;
break;
case 'center':
style.left = '50%';
style.transform = style.transform + ' translateX(-50%)';
break;
case 'right':
style.right = 0;
break;
default:
style.left = data.x + 'px';
}
// console.log(data.x,data.y)
return style;
}
//
const xAlignList = ref([
{
name: '左',
src: 'iconzuoduiqi1',
className: 'left'
},
{
name: '中',
src: 'iconshuipingjuzhong1',
className: 'center'
},
{
name: '右',
src: 'iconyouduiqi1',
className: 'right'
}
])
//
const yAlignList = ref([
{
name: '上',
src: 'icondingduiqi1',
className: 'top'
},
{
name: '中',
src: 'iconchuizhijuzhong1',
className: 'center'
},
{
name: '下',
src: 'icondiduiqi1',
className: 'bottom'
},
])
const alignChangeFn = (type: any,data: any)=>{
posterStore.editComponent[type] = data.className;
}
//
const isChange = ref(true) // truefalse
const goBack = () => {
@ -376,17 +494,17 @@ const save = (callback: any) => {
if (isRepeat.value) return
isRepeat.value = true
posterStore.value.forEach((item:any,index:any)=> {
posterStore.value.forEach((item:any,index:any, originalArr:any)=> {
const box: any = document.getElementById(item.id)
if (box) {
item.width = box.offsetWidth;
item.height = box.offsetHeight;
if (item.type == 'draw') {
// [x,y]
let leftTop = [item.x * 2, item.y * 2]; //
let rightTop = [(item.x + item.width) * 2, item.y * 2]; //
let rightBottom = [(item.x + item.width) * 2, (item.y + item.height) * 2]; //
let leftBottom = [item.x * 2, (item.y + item.height) * 2]; //
let leftTop = [item.x * 1, item.y * 1]; //
let rightTop = [(item.x + item.width) * 1, item.y * 1]; //
let rightBottom = [(item.x + item.width) * 1, (item.y + item.height) * 1]; //
let leftBottom = [item.x * 1, (item.y + item.height) * 1]; //
item.points = [leftTop, rightTop, rightBottom, leftBottom];
}
}
@ -481,12 +599,14 @@ const preview = () => {
}
.preview-iframe {
transform: scale(0.5);
margin: 0 auto;
width: 360px;
height: 640px;
background-size: 100% 640px;
width: 720px;
height: 1280px;
background-size: 100% 1280px;
background-repeat: no-repeat;
position: relative;
transform-origin: left top;
.item-wrap {
position: absolute;
@ -524,8 +644,8 @@ const preview = () => {
.box2,
.box3,
.box4 {
width: 10px;
height: 10px;
width: 20px;
height: 20px;
background-color: #fff;
position: absolute;
border-radius: 50%;
@ -534,26 +654,26 @@ const preview = () => {
}
.box1 {
top: -4px;
left: -4px;
top: -8px;
left: -8px;
cursor: nw-resize;
}
.box2 {
top: -4px;
right: -4px;
top: -8px;
right: -8px;
cursor: ne-resize;
}
.box3 {
left: -4px;
bottom: -4px;
left: -8px;
bottom: -8px;
cursor: sw-resize;
}
.box4 {
bottom: -4px;
right: -4px;
bottom: -8px;
right: -8px;
cursor: se-resize;
}
}

View File

@ -10,7 +10,7 @@
<el-card class="box-card !border-none my-[10px] table-search-wrap" shadow="never">
<el-form :inline="true" :model="posterTableData.searchParam" ref="searchFormDiyPosterRef">
<el-form-item :label="t('posterName')" prop="name">
<el-input v-model="posterTableData.searchParam.name" :placeholder="t('posterNamePlaceholder')" />
<el-input v-model.trim="posterTableData.searchParam.name" :placeholder="t('posterNamePlaceholder')" />
</el-form-item>
<el-form-item :label="t('posterType')" prop="type">
<el-select v-model="posterTableData.searchParam.type" :placeholder="t('posterTypePlaceholder')">
@ -66,14 +66,14 @@
</el-card>
<!--添加海报-->
<el-dialog v-model="dialogVisible" :title="t('addPosterTitle')" width="25%">
<el-dialog v-model="dialogVisible" :title="t('addPosterTitle')" width="350px">
<el-form :model="formData" label-width="90px" ref="formRef" :rules="formRules">
<el-form-item :label="t('posterName')" prop="name">
<el-input v-model="formData.name" :placeholder="t('posterNamePlaceholder')" clearable maxlength="12" show-word-limit class="w-full" />
<el-input v-model.trim="formData.name" :placeholder="t('posterNamePlaceholder')" clearable maxlength="12" show-word-limit class="w-full" />
</el-form-item>
<el-form-item :label="t('posterType')" prop="type">
<el-select v-model="formData.type" :placeholder="t('posterTypePlaceholder')" class="w-full">
<el-select v-model="formData.type" :placeholder="t('posterTypePlaceholder')" class="!w-full">
<el-option v-for="item in posterType" :label="item.name" :value="item.type" :key="item.type"/>
</el-select>
</el-form-item>
@ -151,7 +151,7 @@ const addEvent = async (formEl: FormInstance | undefined) => {
}
//
const loadPosterType = (addon = '')=> {
const loadPosterType = ()=> {
getPosterType({}).then((res:any)=>{
for (let key in posterType) {
delete posterType[key];

View File

@ -126,7 +126,7 @@
<template #dropdown>
<div class="flex flex-col py-[5px] px-[10px]">
<el-button type="primary" link @click="editEvent(row)">{{ t('edit') }}</el-button>
<el-button type="primary" class="mt-[5px] !ml-[0]" link @click="deleteEvent(row)">{{ t('delete') }}</el-button>
<!-- <el-button type="primary" class="mt-[5px] !ml-[0]" link @click="deleteEvent(row)">{{ t('delete') }}</el-button> -->
<el-button type="primary" class="mt-[5px] !ml-[0]" link @click="infoEvent(row)">{{ t('info') }}</el-button>
</div>
</template>

View File

@ -1,164 +0,0 @@
<template>
<el-dialog v-model="showDialog" :title="title" width="500px" :before-close="beforeClose" :destroy-on-close="true">
<el-form :model="formData" label-width="120px" ref="formRef" :rules="formRules" class="page-form">
<el-form-item :label="t('associatedType')" prop="type">
<el-select :placeholder="t('associatedTypePlaceholder')" v-model="formData.type" class="input-width">
<el-option :label="t('hasOne')" value="has_one" />
<el-option :label="t('hasMany')" value="has_many" />
</el-select>
</el-form-item>
<el-form-item :label="t('associatedName')" prop="name">
<el-input v-model="formData.name" :placeholder="t('associatedNamePlaceholder')" class="input-width" />
</el-form-item>
<el-form-item :label="t('addons')" prop="addon">
<el-select v-model="formData.addon" :placeholder="t('addonsPlaceholder')" class="input-width" @change="addonChange">
<el-option v-for="(item, index) in addonList" :label="item.title" :value="item.key" :key="index" />
</el-select>
</el-form-item>
<el-form-item :label="t('associatedModel')" prop="model">
<el-select :placeholder="t('associatedModelPlaceholder')" v-model="formData.model" class="input-width" filterable>
<el-option v-for="item in modelList" :label="item" :value="item" :key="item" />
</el-select>
</el-form-item>
<el-form-item prop="local_key" :label="t('localKey')">
<el-select class="input-width" :placeholder="t('localKeyPlaceholder')" v-model="formData.local_key">
<el-option :label="`${item.name}:${item.comment}`" :value="item.name" v-for="(item, index) in localKeyList" :key="index" />
</el-select>
</el-form-item>
<el-form-item :label="t('foreignKey')" prop="foreign_key">
<el-input v-model="formData.foreign_key" :placeholder="t('foreignKeyPlaceholder')" class="input-width" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
<el-button type="primary" @click="confirm(formRef)">{{ t('confirm') }}</el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup async>
import { ref, computed, toRaw } from 'vue'
import { t } from '@/lang'
import type { FormInstance } from 'element-plus'
import { getGeneratorAllModel, getGeneratorTableColumn, getAddonDevelop } from '@/app/api/tools'
import { cloneDeep } from 'lodash-es'
const showDialog = ref(false)
const title = ref('')
const prop = defineProps({
table_name: {
type: String,
required: true
}
})
/**
* 表单数据
*/
const initialFormData = {
type: 'has_one',
name: '',
addon: 'system',
model: '',
local_key: '',
foreign_key: ''
}
const formData: Record<string, any> = ref({ ...initialFormData })
const formRef = ref<FormInstance>()
//
const formRules = computed(() => {
return {
type: [
{ required: true, message: t('associatedTypePlaceholder'), trigger: 'change' }
],
name: [
{ required: true, message: t('associatedNamePlaceholder'), trigger: 'blur' }
],
addon: [
{ required: true, message: t('addonsPlaceholder'), trigger: 'change' }
],
model: [
{ required: true, message: t('associatedModelPlaceholder'), trigger: 'change' }
],
local_key: [
{ required: true, message: t('localKeyPlaceholder'), trigger: 'change' }
],
foreign_key: [
{ required: true, message: t('foreignKeyPlaceholder'), trigger: 'blur' }
]
}
})
/**
* 获取关联模型
*/
const modelList = ref([])
const getGeneratorAllModelFn = (params:any) => {
getGeneratorAllModel(params).then(res => {
modelList.value = res.data
})
}
/**
* 获取关联键
*/
const localKeyList = ref([])
const getGeneratorTableColumnFn = (key: any) => {
getGeneratorTableColumn({ table_name: key }).then(res => {
localKeyList.value = res.data
})
}
//
const addonList = ref<Array<any>>([])
const getAddonDevelopFn = async () => {
const { data } = await getAddonDevelop({})
addonList.value = [{ title: '系统', key: 'system' }]
addonList.value.push(...data)
getGeneratorAllModelFn({ addon: 'system' })
}
getAddonDevelopFn()
//
const addonChange = (val:any) => {
formData.value.model = ''
getGeneratorAllModelFn({ addon: val })
}
const beforeClose = (next:any) => {
formRef.value?.clearValidate()
next()
}
const emit = defineEmits(['complete'])
/**
* 确认
* @param formEl
*/
const confirm = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(async (valid) => {
if (valid) {
emit('complete', toRaw(formData.value))
showDialog.value = false
}
})
}
const setFormData = async (row: any = null) => {
getGeneratorTableColumnFn(prop.table_name)
if (row) {
formData.value = cloneDeep(row)
} else {
formData.value = cloneDeep(initialFormData)
}
showDialog.value = true
}
defineExpose({
showDialog,
setFormData
})
</script>
<style lang="scss" scoped></style>

View File

@ -4,7 +4,7 @@
<el-form-item :label="t('selectType')" prop="type">
<el-radio-group v-model="formData.select_type">
<el-radio :label="1">{{ t('dictType' )}}</el-radio>
<el-radio :label="2">{{ t('remotePullDown') }}</el-radio>
</el-radio-group>
</el-form-item>
@ -25,18 +25,6 @@
<el-option v-for="item in modelList" :label="item" :value="item" :key="item" />
</el-select>
</el-form-item>
<el-form-item prop="value_key" :label="t('remotePullDownValue')" v-if="formData.select_type == 2">
<el-select class="input-width" :placeholder="t('remotePullDownValuePlaceholder')" v-model="formData.value_key">
<el-option :label="`${item.name}:${item.comment}`" :value="item.name" v-for="(item, index) in keyList" :key="index" />
</el-select>
</el-form-item>
<el-form-item prop="label_key" :label="t('remotePullDownLabel')" v-if="formData.select_type == 2">
<el-select class="input-width" :placeholder="t('remotePullDownLabelPlaceholder')" v-model="formData.label_key">
<el-option :label="`${item.name}:${item.comment}`" :value="item.name" v-for="(item, index) in keyList" :key="index" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -53,8 +41,6 @@ import { t } from '@/lang'
import { getDictAll } from '@/app/api/dict'
import type { FormInstance } from 'element-plus'
import { cloneDeep } from 'lodash-es'
import { getGeneratorAllModel, getGeneratorTableColumn,getAddonDevelop,getGeneratorModelTableColumn } from '@/app/api/tools'
const showDialog = ref(false)
const title = ref('')
/**
@ -73,44 +59,8 @@ const formData: Record<string, any> = ref({ ...initialFormData })
const formRef = ref<FormInstance>()
const dicList = ref<Array<any>>([])
/**
* 获取关联模型
*/
const modelList = ref([])
const getGeneratorAllModelFn = (params:any) => {
getGeneratorAllModel(params).then(res => {
modelList.value = res.data
})
}
//
const addonList = ref<Array<any>>([])
const getAddonDevelopFn = async () => {
let { data } = await getAddonDevelop({})
addonList.value = [{ title: "系统", key: "system" }]
addonList.value.push(...data)
getGeneratorAllModelFn({addon:'system'})
}
getAddonDevelopFn()
//
const addonChange =(val:any)=>{
formData.value.model = ''
getGeneratorAllModelFn({addon:val})
}
const keyList = ref([])
const getGeneratorModelTableColumnFn = (params:any) => {
getGeneratorModelTableColumn(params).then(res => {
keyList.value = res.data
})
}
//
const modelChange = (val:any) => {
// formData.value.model = ''
getGeneratorModelTableColumnFn({model:val})
}
//
const formRules = computed(() => {
@ -126,54 +76,6 @@ const formRules = computed(() => {
},
trigger: 'blur'
}
],
addon: [
{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.select_type == 2 && formData.value.addon == '') {
callback(new Error(t('addonsPlaceholder')))
}else{
callback()
}
},
trigger: 'blur'
}
],
model: [
{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.select_type == 2 && formData.value.model == '') {
callback(new Error(t('associatedModelPlaceholder')))
}else{
callback()
}
},
trigger: 'blur'
}
],
value_key: [
{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.select_type == 2 && formData.value.value_key == '') {
callback(new Error(t('remotePullDownValuePlaceholder')))
}else{
callback()
}
},
trigger: 'blur'
}
],
label_key: [
{
validator: (rule: any, value: any, callback: any) => {
if (formData.value.select_type == 2 && formData.value.label_key == '') {
callback(new Error(t('remotePullDownLabelPlaceholder')))
}else{
callback()
}
},
trigger: 'blur'
}
]
}
@ -203,11 +105,6 @@ const confirm = async (formEl: FormInstance | undefined) => {
const setFormData = async (row: any = null) => {
formData.value = cloneDeep(Object.assign(initialFormData, row))
getDictAllFn()
if(formData.value.model != '')
{
getGeneratorAllModelFn({addon:formData.value.addon})
getGeneratorModelTableColumnFn({model:formData.value.model})
}
showDialog.value = true
}
const beforeClose = (next: any) => {

View File

@ -124,14 +124,6 @@
</template>
</el-table-column>
<!-- <el-table-column :label="t('formValidation')" prop="" min-width="170px">
<template #default="{ row }">
<el-select :placeholder="t('selectPlaceholder')" v-model="row.view_type">
<el-option :label="item.label" :value="item.value" v-for="(item, index) in viewType"
:key="index" />
</el-select>
</template>
</el-table-column> -->
</el-table>
</el-tab-pane>
<el-tab-pane :label="t('generationSettings')" name="generationSettings">
@ -221,25 +213,6 @@
</el-form-item> -->
</el-form>
</el-tab-pane>
<el-tab-pane :label="t('associatedConfiguration')" name="associatedConfiguration">
<div class="mb-[20px]">
<el-button type="primary" class="w-[100px]" @click="addEvent(null, -1)">{{ t('insertAssociated') }}</el-button>
</div>
<el-table :data="formData.relations" size="large">
<el-table-column :label="t('associatedType')" prop="type" min-width="130px" />
<el-table-column :label="t('associatedName')" prop="name" min-width="130px" />
<el-table-column :label="t('addons')" prop="addon" min-width="130px" />
<el-table-column :label="t('associatedModel')" prop="model" min-width="130px" />
<el-table-column :label="t('localKey')" prop="local_key" min-width="130px" />
<el-table-column :label="t('foreignKey')" prop="foreign_key" min-width="130px" />
<el-table-column :label="t('operation')" align="right" min-width="130px">
<template #default="{ row, $index }">
<el-button type="primary" link @click="addEvent(row, $index)">{{ t('edit') }}</el-button>
<el-button type="primary" link @click="deleteEvent($index)">{{ t('delete') }}</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-card>
</div>
@ -264,7 +237,6 @@ import { t } from '@/lang'
import { img } from '@/utils/common'
import { FormInstance, ElMessageBox, ElMessage } from 'element-plus'
import { ArrowLeft } from '@element-plus/icons-vue'
import editAssociated from '@/app/views/tools/code/components/edit-associated.vue'
import editViewType from '@/app/views/tools/code/components/edit-view-type.vue'
import editVerify from '@/app/views/tools/code/components/edit-verify.vue'
import { getGenerateTableInfo, editGenerateTable, getAddonDevelop, generatorCheckFile, generateCreate } from '@/app/api/tools'
@ -466,25 +438,7 @@ const addonChange = async (val: any) => {
if (addonMenuList.value[0]) formData.parent_menu = addonMenuList.value[0].menu_key
}
}
const associatedIndex = ref(0)
const editDialog = ref()
//
const addEvent = (val: any, index: number) => {
associatedIndex.value = index
editDialog.value.setFormData(val)
}
const complete = (row: any) => {
if (associatedIndex.value != -1) {
formData.relations.splice(associatedIndex.value, 1, row)
} else {
formData.relations.unshift(row)
}
}
//
const deleteEvent = (index: number) => {
formData.relations.splice(index, 1)
}
const onSave = async (code: number) => {
const data = cloneDeep(formData)
// if (data.table_column.some(el => { return ['select', 'radio', 'checkbox'].includes(el.view_type) && el.dict_type == '' })) {

View File

@ -141,23 +141,25 @@
<el-dialog v-model="dialogVisible" class="dialog-visible" width="70%" title="代码预览">
<div class="flex h-[50vh]" v-loading="codeLoading">
<el-scrollbar class="h-[100%] w-[270px]">
<el-tree v-if="treeData.length && treeKey != ''" :data="treeData" :props="{ label: 'name', value: 'key' }"
node-key="key" :current-node-key="treeKey" :expand-on-click-node="false" highlight-current
default-expand-all ref="treeRef" @node-click="nodeClick">
<template #default="{ node, data }">
<div class="flex items-center">
<el-icon v-if="data.children">
<Folder v-if="!node.expanded" />
<FolderOpened v-else />
</el-icon>
<el-icon v-else>
<Document />
</el-icon>
<span class="pl-[5px]">{{ data.name }}</span>
</div>
</template>
</el-tree>
<div class="w-[600px]">
<el-tree v-if="treeData.length && treeKey != ''" :data="treeData" :props="{ label: 'name', value: 'key' }"
node-key="key" :current-node-key="treeKey" :expand-on-click-node="false" highlight-current
default-expand-all ref="treeRef" @node-click="nodeClick">
<template #default="{ node, data }">
<div class="flex items-center">
<el-icon v-if="data.children">
<Folder v-if="!node.expanded" />
<FolderOpened v-else />
</el-icon>
<el-icon v-else>
<Document />
</el-icon>
<span class="pl-[5px]">{{ data.name }}</span>
</div>
</template>
</el-tree>
</div>
</el-scrollbar>
<div class="ml-[20px]" style="width: calc(100% - 285px);">
<el-scrollbar class="h-[100%] w-[100%]">
@ -178,6 +180,7 @@ import { img } from '@/utils/common'
import { ElMessageBox, ElMessage } from 'element-plus'
import AddTable from '@/app/views/tools/code/components/add-table.vue'
import type { FormInstance } from 'element-plus'
import { downloadFile } from '@/utils/file'
import { useRouter, useRoute } from 'vue-router'
const route = useRoute()
@ -304,7 +307,6 @@ const generatorCheckFileFn = ((id: any) => {
* 同步or下载
*/
const generateCreateFn = (id: any, generate_type: any) => {
codeTableData.loading = true
generateCreate({ id, generate_type }).then(res => {
ElMessage({
type: 'success',

View File

@ -176,5 +176,15 @@
"write": "可写",
"cloudbuildSuccess": "编译完成",
"showDialogCloseTips": "编译任务尚未完成,关闭将取消编译,是否要继续关闭?"
}
},
"generateNumber": "请输入数字",
"generateEmail": "请输入正确的邮箱",
"generateIdCard": "请输入正确的身份证号",
"generateMobile": "请输入正确的手机号",
"generateNumberOrFloat": "只能输入整数或小数",
"generateMax": "最大输入字符不能超出",
"generateMin": "输入字符不能小于",
"generateUnit": "位",
"startDate": "开始时间",
"endDate": "结束时间"
}

View File

@ -8,8 +8,8 @@ const usePosterStore = defineStore('poster', {
state: () => {
return {
contentBoxWidth: 360, // 360*2=720
contentBoxHeight: 640, // 640*2=1280
contentBoxWidth: 720, // 360*2=720
contentBoxHeight: 1280, // 640*2=1280
id: 0,
name: '', // 页面名称
@ -52,11 +52,11 @@ const usePosterStore = defineStore('poster', {
},
// 组件类型文本textimage图片qrcode二维码
template: {
width: 100, // 宽度
height: 100, // 高度
minWidth: 30, // 最小宽度
minHeight: 30, // 最小高度
x: 0, // 横向坐标 →
width: 200, // 宽度
height: 200, // 高度
minWidth: 60, // 最小宽度
minHeight: 60, // 最小高度
x: 0, // 横向坐标 →
y: 0, // 纵向坐标 ↑
angle: 0, // 旋转角度 0~360
zIndex: 0 // 层级
@ -64,14 +64,18 @@ const usePosterStore = defineStore('poster', {
// 各组件类型的默认值
templateType: {
text: {
height: 30,
minWidth: 60,
minHeight: 22,
fontFamily: '',
fontSize: 20,
height: 60,
minWidth: 120,
minHeight: 44,
fontFamily: 'static/font/SourceHanSansCN-Regular.ttf',
fontSize: 40,
weight: false,
lineHeight: 10,
fontColor: '#303133'
},
image: {},
image: {
shape: 'normal' // 圆形 circle 方形 normal
},
qrcode: {},
// 绘画
draw: {
@ -328,38 +332,40 @@ const usePosterStore = defineStore('poster', {
// 移动事件
mouseDown(e: any, id: any, index: any) {
const box: any = document.getElementById(id);
const disX = e.clientX - box.offsetLeft;
const disY = e.clientY - box.offsetTop;
const disX = (e.clientX * 2 ) - box.offsetLeft;
const disY = (e.clientY * 2 ) - box.offsetTop;
// 鼠标移动时
document.onmousemove = (e) => {
let clientX = e.clientX * 2;
let clientY = e.clientY * 2;
if (this.contentBoxWidth == box.offsetWidth) {
box.style.left = 0
} else {
box.style.left = e.clientX - disX + 'px'
box.style.left = (clientX - disX) + 'px'
}
box.style.top = e.clientY - disY + 'px';
box.style.top = (clientY - disY) + 'px';
// 边界判断
if (e.clientX - disX < 0) {
if (clientX - disX < 0) {
box.style.left = 0
}
if (e.clientX - disX > this.contentBoxWidth - box.offsetWidth) {
if (clientX - disX > this.contentBoxWidth - box.offsetWidth) {
box.style.left = this.contentBoxWidth - box.offsetWidth + 'px'
}
if (e.clientY - disY < 0) {
if (clientY - disY < 0) {
box.style.top = 0
}
if (e.clientY - disY > this.contentBoxHeight - box.offsetHeight) {
if (clientY - disY > this.contentBoxHeight - box.offsetHeight) {
box.style.top = this.contentBoxHeight - box.offsetHeight + 'px'
}
this.value[index].x = box.offsetLeft;
this.value[index].y = box.offsetTop
this.value[index].y = box.offsetTop;
};

View File

@ -1 +1,2 @@
/* addon iconfont */
@import "addon/o2o/iconfont.css";
@import "addon/tourism/iconfont.css";

View File

@ -0,0 +1,38 @@
@font-face {
font-family: "o2o"; /* Project id 4412516 */
src: url('//at.alicdn.com/t/c/font_4412516_cacqsbew46.woff2?t=1705720131974') format('woff2'),
url('//at.alicdn.com/t/c/font_4412516_cacqsbew46.woff?t=1705720131974') format('woff'),
url('//at.alicdn.com/t/c/font_4412516_cacqsbew46.ttf?t=1705720131974') format('truetype');
}
.o2o {
font-family: "o2o" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.o2o-icon-danhanghuadong:before {
content: "\e66f";
}
.o2o-icon-yuanjiao:before {
content: "\e6c0";
}
.o2o-icon-gl-square:before {
content: "\ea92";
}
.o2o-icon-sousuo12:before {
content: "\e699";
}
.o2o-icon-sousuo11:before {
content: "\e6d4";
}
.o2o-icon-jishi:before {
content: "\e600";
}

View File

@ -0,0 +1,51 @@
{
"id": "4412516",
"name": "上门服务",
"font_family": "o2o",
"css_prefix_text": "o2o-icon-",
"description": "",
"glyphs": [
{
"icon_id": "30621139",
"name": "单行滑动",
"font_class": "danhanghuadong",
"unicode": "e66f",
"unicode_decimal": 58991
},
{
"icon_id": "7149037",
"name": "圆角",
"font_class": "yuanjiao",
"unicode": "e6c0",
"unicode_decimal": 59072
},
{
"icon_id": "7594344",
"name": "20gl-square",
"font_class": "gl-square",
"unicode": "ea92",
"unicode_decimal": 60050
},
{
"icon_id": "10133070",
"name": "搜索",
"font_class": "sousuo12",
"unicode": "e699",
"unicode_decimal": 59033
},
{
"icon_id": "14652583",
"name": "搜索",
"font_class": "sousuo11",
"unicode": "e6d4",
"unicode_decimal": 59092
},
{
"icon_id": "6818781",
"name": "技师",
"font_class": "jishi",
"unicode": "e600",
"unicode_decimal": 58880
}
]
}

View File

@ -0,0 +1,58 @@
@font-face {
font-family: "tourism"; /* Project id 4137250 */
src: url('//at.alicdn.com/t/c/font_4137250_st1ha9l0k1e.woff2?t=1687685028672') format('woff2'),
url('//at.alicdn.com/t/c/font_4137250_st1ha9l0k1e.woff?t=1687685028672') format('woff'),
url('//at.alicdn.com/t/c/font_4137250_st1ha9l0k1e.ttf?t=1687685028672') format('truetype');
}
.tourism {
font-family: "tourism" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.tourism-icon-feiji:before {
content: "\e600";
}
.tourism-icon-lvyou:before {
content: "\e6a9";
}
.tourism-icon-lvyouchanpin:before {
content: "\e63b";
}
.tourism-icon-lvyou1:before {
content: "\e623";
}
.tourism-icon-lvyou2:before {
content: "\e601";
}
.tourism-icon-lvyou3:before {
content: "\e60c";
}
.tourism-icon-lvyoubaochedingdan:before {
content: "\e612";
}
.tourism-icon-lvyou4:before {
content: "\e653";
}
.tourism-icon-lvyou5:before {
content: "\e610";
}
.tourism-icon-lvyouguanguang:before {
content: "\e87e";
}
.tourism-icon-lvyou6:before {
content: "\e642";
}

View File

@ -0,0 +1,86 @@
{
"id": "4137250",
"name": "旅游业",
"font_family": "tourism",
"css_prefix_text": "tourism-icon-",
"description": "",
"glyphs": [
{
"icon_id": "1443",
"name": "飞机",
"font_class": "feiji",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "446824",
"name": "旅游",
"font_class": "lvyou",
"unicode": "e6a9",
"unicode_decimal": 59049
},
{
"icon_id": "1167173",
"name": "旅游产品",
"font_class": "lvyouchanpin",
"unicode": "e63b",
"unicode_decimal": 58939
},
{
"icon_id": "1354920",
"name": "旅游",
"font_class": "lvyou1",
"unicode": "e623",
"unicode_decimal": 58915
},
{
"icon_id": "1505555",
"name": "旅游",
"font_class": "lvyou2",
"unicode": "e601",
"unicode_decimal": 58881
},
{
"icon_id": "2121726",
"name": "旅游",
"font_class": "lvyou3",
"unicode": "e60c",
"unicode_decimal": 58892
},
{
"icon_id": "2357494",
"name": "旅游包车订单",
"font_class": "lvyoubaochedingdan",
"unicode": "e612",
"unicode_decimal": 58898
},
{
"icon_id": "3944019",
"name": "旅游",
"font_class": "lvyou4",
"unicode": "e653",
"unicode_decimal": 58963
},
{
"icon_id": "4838220",
"name": "旅游",
"font_class": "lvyou5",
"unicode": "e610",
"unicode_decimal": 58896
},
{
"icon_id": "7444178",
"name": "旅游观光",
"font_class": "lvyouguanguang",
"unicode": "e87e",
"unicode_decimal": 59518
},
{
"icon_id": "9748082",
"name": "旅游",
"font_class": "lvyou6",
"unicode": "e642",
"unicode_decimal": 58946
}
]
}

17
admin/src/utils/file.ts Normal file
View File

@ -0,0 +1,17 @@
/**
*
* @param file
* @param fileName
*/
export function downloadFile (file: any, fileName: string) {
const blob = new Blob([file], { type: 'application/octet-stream;charset=UTF-8' })
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
}

View File

@ -0,0 +1,44 @@
import Test from "@/utils/test"
export default {
/**
*
*/
numberVerify(rule: any, value: any, callback: any) => {
if (!Test.digits(value)) {
callback(new Error(t('generateNumber')))
} else {
callback()
}
},
/**
*
*/
emailVerify(rule: any, value: any, callback: any) => {
if (!Test.email(value)) {
callback(new Error(t('generateEmail')))
} else {
callback()
}
},
/**
*
*/
idCardVerify(rule: any, value: any, callback: any) => {
if (!Test.idCard(value)) {
callback(new Error(t('generateIdCard')))
} else {
callback()
}
},
/**
*
*/
mobileVerify(rule: any, value: any, callback: any) => {
if (!Test.idCard(value)) {
callback(new Error(t('generateMobile')))
} else {
callback()
}
}
}

View File

@ -4,6 +4,10 @@ import com.niu.boot.config.BootConfig;
import com.niu.boot.process.EnvironmentValidator;
import com.niu.boot.process.ProcessMonitor;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class Boot {
public static void main(String[] args) {
@ -27,6 +31,18 @@ public class Boot {
System.exit(0);
}
}
for (String arg: args) {
if (arg.equals("--install-addon")) {
try (RandomAccessFile raf = new RandomAccessFile("install_addon.dat", "rw");
FileChannel channel = raf.getChannel()) {
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 100);
buffer.put("install-addon".getBytes());
} catch (Exception e) {
}
}
}
bootConfig.printArguments();
new ProcessMonitor(bootConfig).start();
Runtime.getRuntime().addShutdownHook(new ProcessMonitor.Shutdown());

View File

@ -348,8 +348,15 @@
<groupId>com.freewayso</groupId>
<artifactId>image-combiner</artifactId>
</dependency>
<!--velocity代码生成 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<finalName>niucloud-core</finalName>
<resources>

View File

@ -14,7 +14,7 @@ public class GlobalConfig {
/**
* 表前缀配置
*/
public static String tablePrefix = "ns_";
public static String tablePrefix = "nc_";
/**
* 配置的默认语言包
@ -51,6 +51,12 @@ public class GlobalConfig {
*/
public static String version = "0.0.2";
/**
* 应用key
*
*/
public static String appKey = "niucloud-admin";
/**
* 默认访问路径
**/

View File

@ -73,13 +73,13 @@ public final class AddonModuleContext {
readResult = true;
}
} catch (Exception e) {
e.printStackTrace();
// e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
// e.printStackTrace();
}
}
}
@ -98,13 +98,13 @@ public final class AddonModuleContext {
context = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}
} catch (Exception e) {
e.printStackTrace();
// e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
// e.printStackTrace();
}
}
}
@ -124,13 +124,13 @@ public final class AddonModuleContext {
context = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}
} catch (Exception e) {
e.printStackTrace();
// e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
// e.printStackTrace();
}
}
}
@ -151,13 +151,13 @@ public final class AddonModuleContext {
}
} catch (Exception e) {
// ignore
e.printStackTrace();
// e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
// e.printStackTrace();
}
}
}
@ -188,20 +188,20 @@ public final class AddonModuleContext {
context = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}
} catch (Exception e) {
e.printStackTrace();
// e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
// e.printStackTrace();
}
}
if (openInputStream != null) {
try {
openInputStream.close();
} catch (IOException e) {
e.printStackTrace();
// e.printStackTrace();
}
}
}

View File

@ -17,6 +17,8 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 站点资源过滤
@ -68,6 +70,13 @@ public class WebSiteResourceFilter implements Filter {
request.getRequestDispatcher("/wap/index.html").forward(request, response);
return;
}
Matcher matcher = Pattern.compile("^/MP_verify_(\\w+)\\.txt$").matcher(requestUri);
if (matcher.find()) {
String verifyCode = matcher.group(1);
response.setContentType("text/plain;charset=UTF-8");
response.getWriter().write(verifyCode);
return;
}
// =======================================================================================//
// =========其他业务处理
// =======================================================================================//

View File

@ -1,17 +1,27 @@
package com.niu.core.common.config.executable.initialize;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.niu.core.common.utils.file.FileTools;
import com.niu.core.common.component.context.SpringContext;
import com.niu.core.common.component.context.WebAppEnvs;
import com.niu.core.common.config.GlobalConfig;
import com.niu.core.common.utils.json.JsonLoadUtils;
import com.niu.core.entity.addon.Addon;
import com.niu.core.entity.site.Site;
import com.niu.core.mapper.site.SiteMapper;
import com.niu.core.service.admin.install.IInstallSystemService;
import com.niu.core.service.core.addon.AddonInstallJavaTools;
import com.niu.core.service.core.addon.AddonInstallTools;
import com.niu.core.service.core.addon.ICoreAddonService;
import com.niu.core.service.core.app.tools.SQLScriptRunnerTools;
import com.niu.core.service.core.schedule.ICoreScheduleService;
import com.niu.core.service.core.sys.ICoreMenuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
@ -20,10 +30,19 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Spring Context声明周期刷新Context后执行
@ -43,13 +62,12 @@ public class CoreSpringContextListener implements ApplicationListener<ContextRef
log.info("当前应用运行环境:" + GlobalConfig.runActive);
log.info("当前应用运行环境工作目录:" + WebAppEnvs.get());
if (this.isInit()) {
// 第一次安装时初始化创建
//this.initSqlSchema();
//this.initSqlData();
// 初始话菜单
this.initMenu();
// 初始话计划任务
this.initSchedule();
// 安裝插件
if (this.isInstallAddon()) this.installAddon();
// 创建完成
this.setCreated();
Site site = new Site();
@ -147,13 +165,7 @@ public class CoreSpringContextListener implements ApplicationListener<ContextRef
{
return true;
}
return false;
/* String initedContent = FileTools.readTempContent(GlobalConfig.applicationName + "/inited");
if ("init".equals(initedContent)) {
return true;
}
return false;*/
}
/**
@ -163,4 +175,94 @@ public class CoreSpringContextListener implements ApplicationListener<ContextRef
FileTools.writeTempContent(GlobalConfig.applicationName + "/inited", "created");
}
/**
* 安裝插件
*/
private void installAddon() {
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
int delaySeconds = 30; // 延迟是为了解决mybatis-plus-join的初始化bug避免mybatis调用错误
executorService.schedule(() -> {
log.info("开始安装插件");
try {
// 获取本地所有的插件
List<File> localAddons = Files.list(Paths.get(WebAppEnvs.get().webRootDownAddon))
.map(path -> path.toFile())
.filter(file -> file.isDirectory())
.collect(Collectors.toList());
System.out.println("localAddons");
System.out.println(localAddons);
AddonInstallTools addonInstallTools = SpringContext.bean(AddonInstallTools.class);
ICoreMenuService coreMenuService = SpringContext.bean(ICoreMenuService.class);
ICoreScheduleService coreScheduleService = SpringContext.bean(ICoreScheduleService.class);
ICoreAddonService coreAddonService = SpringContext.bean(ICoreAddonService.class);
for (File file : localAddons) {
log.info("安装插件" + new File(file, "info.json").getAbsolutePath());
if (new File(file, "info.json").exists()) {
JSONObject info = JSONUtil.parseObj(JsonLoadUtils.loadJsonString(new File(file, "info.json")));
String addon = info.getStr("key");
// 合并文件
addonInstallTools.installDir(addon);
// 合并依赖
addonInstallTools.installDepend(addon);
// 合并uniapp文件
addonInstallTools.installUniapp(addon);
// 安装菜单
coreMenuService.installAddonMenu(addon);
// 安装数据库
File installSql = new File(file, "sql/install.sql");
if (installSql.exists()) {
String sqlContent = FileUtils.readFileToString(installSql, "UTF-8");
sqlContent = sqlContent.replace("{{prefix}}", GlobalConfig.tablePrefix);
SQLScriptRunnerTools.execScript(sqlContent);
}
coreScheduleService.installAddonSchedule(addon);
coreAddonService.set(JSONUtil.toBean(info, Addon.class));
AddonInstallJavaTools.addAddonJson(addon);
}
}
} catch (Exception e) {
log.warn("插件安装失败");
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}, delaySeconds, TimeUnit.SECONDS);
}
/**
* 是否安装插件
*
* @return
*/
private boolean isInstallAddon() {
try (RandomAccessFile raf = new RandomAccessFile("install_addon.dat", "rw");
FileChannel channel = raf.getChannel()) {
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 100);
// 读取数据
byte[] data = new byte[buffer.limit()];
buffer.get(data);
String message = new String(data).trim();
if (message.equals("install-addon")) {
clearBuffer(buffer);
return true;
} else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private void clearBuffer(MappedByteBuffer buffer) {
buffer.rewind(); // 将位置重置为 0
for (int i = 0; i < buffer.limit(); i++) {
buffer.put(i, (byte) 0);
}
}
}

View File

@ -0,0 +1,150 @@
package com.niu.core.common.utils;
import cn.hutool.core.date.DateUtil;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.util.Arrays;
import java.util.List;
public class DatabaseBackup {
private String dbUrl;
private String dbUser;
private String dbPassword;
private static final int MAX_FILE_SIZE = 6 * 1024 * 1024;
private String backupFilePath;
private List<String> filter;
public DatabaseBackup(String dbUrl, String dbUser, String dbPassword) {
this.dbUrl = dbUrl;
this.dbUser = dbUser;
this.dbPassword = dbPassword;
}
/**
* 设置备份目录
* @param path
* @return
*/
public DatabaseBackup setDir(String path) {
this.backupFilePath = path;
return this;
}
/**
* 设置无需备份的表
* @param filter
* @return
*/
public DatabaseBackup setFilter(String[] filter) {
this.filter = Arrays.asList(filter);
return this;
}
/**
* 备份数据库
*/
public void backup() {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
FileWriter writer = null;
File file = null;
String fileName = DateUtil.format(DateUtil.date(), "yyyyMMdd");
int fileCounter = 0;
try {
// 建立数据库连接
connection = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
// 获取所有表名
statement = connection.prepareStatement("SHOW TABLES");
resultSet = statement.executeQuery();
file = new File(this.backupFilePath + fileName + ".sql");
writer = new FileWriter(file);
while (resultSet.next()) {
String tableName = resultSet.getString(1);
if (this.filter.size() > 0 && this.filter.contains(tableName)) continue;
writer.write("-- Table structure for table `" + tableName + "`\n");
writer.write("DROP TABLE IF EXISTS `" + tableName + "`;\n");
statement = connection.prepareStatement("SHOW CREATE TABLE " + tableName);
ResultSet createTableResult = statement.executeQuery();
if (createTableResult.next()) {
writer.write(createTableResult.getString(2) + ";\n\n");
}
// 备份表数据
writer.write("-- Dumping data for table `" + tableName + "`\n");
statement = connection.prepareStatement("SELECT * FROM " + tableName);
ResultSet dataResult = statement.executeQuery();
int isRestart = 0;
while (dataResult.next()) {
StringBuilder sqlBuilder = null;
if (dataResult.isFirst() || isRestart == 1) {
sqlBuilder = new StringBuilder("INSERT INTO " + tableName + " VALUES\n(");
isRestart = 0;
} else {
sqlBuilder = new StringBuilder("(");
}
for (int i = 1; i <= dataResult.getMetaData().getColumnCount(); i++) {
if (i > 1) sqlBuilder.append(", ");
Object value = dataResult.getObject(i);
if (value instanceof String || value instanceof java.util.Date) {
sqlBuilder.append("'").append(value).append("'");
} else {
sqlBuilder.append(value);
}
}
if (dataResult.isLast()) {
sqlBuilder.append(");\n");
} else if (file.length() >= MAX_FILE_SIZE) {
isRestart = 1;
sqlBuilder.append(");\n");
} else {
sqlBuilder.append("),\n");
}
writer.write(sqlBuilder.toString());
if (isRestart == 1) {
writer.close();
fileCounter++;
file = new File(this.backupFilePath + fileName + "-" + fileCounter + ".sql");
writer = new FileWriter(file);
}
}
writer.write("\n");
}
} catch (IOException | SQLException e) {
throw new RuntimeException(e.getMessage());
} finally {
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
if (writer != null) {
writer.flush(); // 确保数据被写入文件
writer.close();
}
} catch (SQLException | IOException e) {
throw new RuntimeException(e.getMessage());
}
}
}
}

View File

@ -180,7 +180,7 @@ public class NiucloudUtils {
* niucloud云服务器
*/
public static class Cloud {
private String baseUrl = "http://oss.niucloud.com/";
private String baseUrl = "http://8.152.194.94:8000/";
private String url;

View File

@ -3,6 +3,7 @@ package com.niu.core.common.utils;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import com.niu.core.common.component.context.SpringContext;
import com.niu.core.common.exception.CommonException;
import com.niu.core.enums.channel.WechatEncryptionTypeEnum;
import com.niu.core.service.core.weapp.ICoreWeappConfigService;
import com.niu.core.service.core.weapp.vo.WeappConfigVo;
@ -30,6 +31,8 @@ public class WechatUtils {
WxMpService service = new WxMpServiceImpl();
WxMpDefaultConfigImpl wxMpDefaultConfig = new WxMpDefaultConfigImpl();
WechatConfigVo wechatConfigVo = coreWechatConfigService.getWechatConfig(siteId);
if (wechatConfigVo.getAppId().isEmpty() || wechatConfigVo.getAppSecret().isEmpty()) throw new CommonException("微信公众号未配置完善");
wxMpDefaultConfig.setAppId(wechatConfigVo.getAppId());
wxMpDefaultConfig.setSecret(wechatConfigVo.getAppSecret());
wxMpDefaultConfig.setToken(wechatConfigVo.getToken());
@ -52,6 +55,8 @@ public class WechatUtils {
WxMaDefaultConfigImpl wxMaDefaultConfig = new WxMaDefaultConfigImpl();
WeappConfigVo weappConfigVo = coreWeappConfigService.getWeappConfig(siteId);
if (weappConfigVo.getAppId().isEmpty() || weappConfigVo.getAppSecret().isEmpty()) throw new CommonException("微信小程序未配置完善");
wxMaDefaultConfig.setAppid(weappConfigVo.getAppId());
wxMaDefaultConfig.setSecret(weappConfigVo.getAppSecret());
wxMaDefaultConfig.setToken(weappConfigVo.getToken());

View File

@ -3,9 +3,12 @@ package com.niu.core.common.utils.file;
import cn.hutool.core.io.FileUtil;
import com.niu.core.common.Constants;
import com.niu.core.common.utils.system.RuntimeTools;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FileTools {
@ -210,4 +213,25 @@ public class FileTools {
}
}
/**
* 创建 FileUtils.copyDirectory 需要排除的目录
*
* @param dirs
* @return
*/
public static IOFileFilter createExclusionFilter(String[] dirs) {
// 定义要排除的目录
List<String> excludedDirs = Arrays.asList(dirs);
// 创建一个过滤器来排除特定子目录
IOFileFilter excludeSubDirsFilter = FileFilterUtils.trueFileFilter(); // 初始化为 false表示过滤所有文件或目录
// 循环创建过滤器
for (String dirName : excludedDirs) {
IOFileFilter tempFilter = FileFilterUtils.nameFileFilter(dirName);
excludeSubDirsFilter = FileFilterUtils.and(excludeSubDirsFilter, FileFilterUtils.notFileFilter(tempFilter));
}
return excludeSubDirsFilter;
}
}

View File

@ -4,11 +4,9 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
import com.niu.core.common.domain.Result;
import com.niu.core.enums.addon.AddonTypeEnum;
import com.niu.core.service.admin.addon.IAddonService;
import com.niu.core.service.admin.upgrade.IUpgradeService;
import com.niu.core.service.core.addon.vo.InstallAddonListVo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
@ -22,13 +20,47 @@ import java.util.Map;
@SaCheckLogin
public class UpgradeController {
@Resource
IUpgradeService upgradeService;
/**
* 获取升级内容
*/
@GetMapping("")
public Result<?> getUpgradeContent() {
return Result.success(upgradeService.getUpgradeContent(""));
}
/**
* 获取升级内容
*/
@GetMapping("/{addon}")
public Result<?> getUpgradeContent(@PathVariable(value = "addon") String addon) {
return Result.success(upgradeService.getUpgradeContent(addon));
}
/**
* 升级
*/
@PostMapping("")
public Result<?> upgrade() {
return Result.success(upgradeService.upgrade(""));
}
/**
* 升级
*/
@PostMapping("/{addon}")
public Result<?> upgrade(@PathVariable(value = "addon") String addon) {
return Result.success(upgradeService.upgrade(addon));
}
/**
* 获取正在进行的升级任务
*/
@GetMapping("/task")
public Result<?> getUpgradeTask() {
Object result = null;
return Result.success(result);
return Result.success(upgradeService.getUpgradeTask());
}
/**
@ -36,6 +68,7 @@ public class UpgradeController {
*/
@PostMapping("/execute")
public Result execute() {
upgradeService.execute();
return Result.success();
}
@ -44,6 +77,7 @@ public class UpgradeController {
*/
@PostMapping("/clear")
public Result clearUpgradeTask() {
upgradeService.clearUpgradeTask(0);
return Result.success();
}
}

View File

@ -3,7 +3,6 @@ package com.niu.core.controller.adminapi.channel;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.niu.core.common.domain.Result;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.service.admin.dict.param.DictDataParam;
import com.niu.core.service.core.channel.ICoreH5Service;
import com.niu.core.service.core.channel.param.SetH5Param;
import com.niu.core.service.core.channel.vo.H5ConfigVo;

View File

@ -0,0 +1,123 @@
package com.niu.core.controller.adminapi.dict;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.domain.Result;
import com.niu.core.service.admin.dict.IDictService;
import com.niu.core.service.admin.dict.param.DictDataParam;
import com.niu.core.service.admin.dict.param.DictParam;
import com.niu.core.service.admin.dict.param.DictSearchParam;
import com.niu.core.service.admin.dict.vo.DictInfoVo;
import com.niu.core.service.admin.dict.vo.DictListVo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 字典数据管理
*/
@RestController
@RequestMapping("/adminapi/dict")
@SaCheckLogin
public class DictController {
@Resource
IDictService dictService;
/**
* 字典列表
* @param pageParam
* @param searchParam
* @return
*/
@GetMapping("/dict")
public Result<PageResult<DictListVo>> info(@Validated PageParam pageParam, @Validated DictSearchParam searchParam) {
PageResult<DictListVo> list = dictService.getPage(pageParam, searchParam);
return Result.success(list);
}
/**
* 字典数据详情
* @param id 主键ID
* @return Result<DictInfoVo>
*/
@GetMapping("/dict/{id}")
public Result<DictInfoVo> info(@Validated @PathVariable("id") Integer id) {
DictInfoVo detail = dictService.info(id);
return Result.success(detail);
}
/**
* 字典数据详情
* @param type
* @return Result<DictInfoVo>
*/
@GetMapping("dictionary/type/{type}")
public Result<DictInfoVo> getKeyInfo(@Validated @PathVariable("type") String type) {
DictInfoVo detail = dictService.info(type);
return Result.success(detail);
}
/**
* 字典数据添加
* @param addParam 参数
* @return Result<Object>
*/
@PostMapping("/dict")
public Result<Object> add(@Validated @RequestBody DictParam addParam) {
dictService.add(addParam);
return Result.success();
}
/**
* 字典数据编辑
*
* @param editParam 参数
* @return Result<Object>
*/
@PutMapping("/dict/{id}")
public Result<Object> edit(@Validated @PathVariable("id") Integer id, @Validated @RequestBody DictParam editParam) {
dictService.edit(id, editParam);
return Result.success();
}
/**
* 字典数据编辑
*
* @param editParam 参数
* @return Result<Object>
*/
@PutMapping("/dictionary/{id}")
public Result<Object> addDictData(@Validated @PathVariable("id") Integer id, @Validated @RequestBody DictDataParam editParam) {
dictService.addDictData(id, editParam);
return Result.success();
}
/**
* 字典数据删除
*
* @param id 参数
* @return Result<Object>
*/
@DeleteMapping("/dict/{id}")
public Result<Object> del(@Validated @PathVariable("id") Integer id) {
dictService.del(id);
return Result.success();
}
/**
* 字典数据列表
* @return Result<DictListVo>
*/
@GetMapping("/all")
public Result<List<DictListVo>> getAll() {
return Result.success(dictService.getAll());
}
}

View File

@ -1,72 +0,0 @@
package com.niu.core.controller.adminapi.dict;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.niu.core.common.domain.Result;
import com.niu.core.service.admin.dict.IDictDataService;
import com.niu.core.service.admin.dict.param.DictDataParam;
import com.niu.core.service.admin.dict.vo.DictDataInfoVo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 字典数据管理
*/
@RestController
@RequestMapping("/api/data")
@SaCheckLogin
public class DictDataController {
@Resource
IDictDataService dictDataService;
/**
* 字典数据详情
*
* @param id 主键ID
* @return Result<DictDataInfoVo>
*/
@GetMapping("/info")
public Result<DictDataInfoVo> info(@Validated @RequestParam("id") Integer id) {
DictDataInfoVo detail = dictDataService.info(id);
return Result.success(detail);
}
/**
* 字典数据添加
*
* @param addParam 参数
* @return Result<Object>
*/
@PostMapping("/add")
public Result<Object> add(@Validated @RequestBody DictDataParam addParam) {
dictDataService.add(addParam);
return Result.success();
}
/**
* 字典数据编辑
*
* @param editParam 参数
* @return Result<Object>
*/
@PostMapping("/edit")
public Result<Object> edit(Integer id, @Validated @RequestBody DictDataParam editParam) {
dictDataService.edit(id, editParam);
return Result.success();
}
/**
* 字典数据删除
*
* @param id 参数
* @return Result<Object>
*/
@PostMapping("/del")
public Result<Object> del(@Validated @RequestBody Integer id) {
dictDataService.del(id);
return Result.success();
}
}

View File

@ -0,0 +1,160 @@
package com.niu.core.controller.adminapi.generator;
import com.niu.core.common.component.context.WebAppEnvs;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.domain.Result;
import com.niu.core.service.admin.generator.IGenerateService;
import com.niu.core.service.admin.generator.param.GenerateCodeParam;
import com.niu.core.service.admin.generator.param.GenerateEditParam;
import com.niu.core.service.admin.generator.param.GenerateParam;
import com.niu.core.service.admin.generator.param.GenerateSearchParam;
import com.niu.core.service.admin.generator.vo.*;
import com.niu.core.service.core.generator.vo.CoreGenerateTemplateVo;
import org.apache.commons.io.IOUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("adminapi/generator")
public class GenerateController {
@Resource
IGenerateService generateService;
/**
* 生成列表
* @param pageParam
* @param searchParam
* @return
*/
@GetMapping("/generator")
public Result<PageResult<GenerateListVo>> list(@Validated PageParam pageParam,
@Validated GenerateSearchParam searchParam) {
PageResult<GenerateListVo> list = generateService.getPage(pageParam, searchParam);
return Result.success(list);
}
/**
* 生成详情
* @param id
* @return
*/
@GetMapping("/generator/{id}")
public Result<GenerateDetailVo> detail(@PathVariable("id") Integer id) {
GenerateDetailVo detail = generateService.getInfo(id);
return Result.success(detail);
}
/**
* 添加代码生成
* @param generateParam
* @return
*/
@PostMapping("/generator")
public Result<Map<String, Integer>> add(@Validated @RequestBody GenerateParam generateParam) {
Integer id = generateService.add(generateParam);
Map<String, Integer> map = new HashMap<>();
map.put("id", id);
return Result.success( map);
}
/**
* 编辑代码生成
* @param id
* @param generateParam
* @return
*/
@PutMapping("/generator/{id}")
public Result<Object> edit(@PathVariable("id") Integer id, @Validated @RequestBody GenerateEditParam generateParam) {
generateService.edit(id, generateParam);
return Result.success();
}
/**
* 删除代码生成
* @param id
* @return
*/
@DeleteMapping("/generator/{id}")
public Result<Object> del(@PathVariable("id") Integer id) {
generateService.del(id);
return Result.success();
}
/**
* 下载生成代码
* @param generateCodeParam
* @return
*/
@PostMapping("/download")
public Result<Map<String, String>> create(@Validated @RequestBody GenerateCodeParam generateCodeParam) {
generateService.generate(generateCodeParam);
Map<String, String> data = new HashMap<>();
data.put("file", "upload/generate/package.zip");
return Result.success(data);
}
/**
* 数据表列表
* @param content
* @return
*/
@GetMapping("/table")
public Result<List<Map<String, Object>>> tableList(String name, String content) {
List<Map<String, Object>> list = generateService.tableList(name, content);
return Result.success(list);
}
/**
* 生成预览
* @param id
* @return
*/
@GetMapping("/preview/{id}")
public Result<List<GeneratePreviewVo>> preview(@PathVariable("id") Integer id) {
return Result.success(generateService.preview(id));
}
/**
* 检测文件
* @param id
* @return
*/
@GetMapping("/check_file")
public Result<Integer> checkFile(String id) {
return Result.success(1,"操作成功", generateService.checkFile(id));
}
/**
* 数据表字段
* @param tableName
* @return
*/
@GetMapping("/table_column")
public Result<List<TableFiledVo>> getTableColumn(String tableName) {
List<TableFiledVo> list = generateService.getTableColumn(tableName);
return Result.success(list);
}
}

View File

@ -5,6 +5,7 @@ import cn.hutool.json.JSONObject;
import com.niu.core.common.domain.Result;
import com.niu.core.service.admin.notice.INoticeService;
import com.niu.core.service.admin.notice.ISmsService;
import com.niu.core.service.admin.notice.param.EditMessageStatusParam;
import com.niu.core.service.admin.notice.vo.SmsTypeVo;
import com.niu.core.service.core.notice.vo.AddonNoticeListVo;
import com.niu.core.service.core.notice.vo.NoticeInfoVo;
@ -85,4 +86,15 @@ public class NoticeController {
smsService.setConfig(smsType, data);
return Result.success();
}
/**
* 消息启动与关闭
*
* @return
*/
@PostMapping("/notice/editstatus")
public Result editStatus(@Validated @RequestBody EditMessageStatusParam param) {
noticeService.editMessageStatus(param);
return Result.success();
}
}

View File

@ -110,4 +110,15 @@ public class SysMenuController {
return Result.success(sysMenuService.menuTree());
}
/**
* 获取菜单类型
* @param addon
* @return
*/
@GetMapping("/menu/dir/{addon}")
public Result<JSONArray> getMenuByTypeDir(@PathVariable("addon") String addon) {
return Result.success(sysMenuService.getMenuByTypeDir(addon));
}
}

View File

@ -5,14 +5,15 @@ import com.niu.core.common.domain.Result;
import com.niu.core.common.domain.PageResult;
import com.niu.core.enums.poster.PosterTypeEnum;
import com.niu.core.service.admin.sys.ISysPosterService;
import com.niu.core.service.admin.sys.param.SysPosterParam;
import com.niu.core.service.admin.sys.param.SysPosterSearchParam;
import com.niu.core.service.admin.sys.param.*;
import com.niu.core.service.admin.sys.vo.SysPosterInfoVo;
import com.niu.core.service.admin.sys.vo.SysPosterListVo;
import com.niu.core.common.domain.PageParam;
import com.niu.core.service.admin.sys.param.SysPosterTemplateSearchParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 海报控制器
@ -27,16 +28,23 @@ public class SysPosterController {
ISysPosterService sysPosterService;
/**
* 海报列表
* @param pageParam 分页
* 海报分页列表
* @param searchParam 搜索条件
* @return Result<PageResult<SysPosterListVo>>
*/
@GetMapping("")
public Result<PageResult<SysPosterListVo>> page(PageParam pageParam, @Validated SysPosterSearchParam searchParam) {
return Result.success(sysPosterService.page(pageParam, searchParam));
}
/**
* 海报列表
* @param searchParam 搜索条件
* @return Result<List<SysPosterListVo>>
*/
@GetMapping("/list")
public Result<PageResult<SysPosterListVo>> list(@Validated PageParam pageParam,
@Validated SysPosterSearchParam searchParam) {
PageResult<SysPosterListVo> list = sysPosterService.list(pageParam, searchParam);
return Result.success(list);
public Result<List<SysPosterListVo>> list(@Validated SysPosterSearchParam searchParam) {
return Result.success(sysPosterService.list(searchParam));
}
/**
@ -44,8 +52,8 @@ public class SysPosterController {
* @param id 主键ID
* @return Result<SysPosterInfoVo>
*/
@GetMapping("/info")
public Result<SysPosterInfoVo> info(@Validated @RequestParam("id") Integer id) {
@GetMapping("/{id}")
public Result<SysPosterInfoVo> info(@PathVariable Integer id) {
SysPosterInfoVo info = sysPosterService.info(id);
return Result.success(info);
}
@ -55,7 +63,7 @@ public class SysPosterController {
* @param addParam 添加参数
* @return Result<Object>
*/
@PostMapping("/add")
@PostMapping("")
public Result<Object> add(@Validated @RequestBody SysPosterParam addParam) {
sysPosterService.add(addParam);
return Result.success();
@ -66,7 +74,7 @@ public class SysPosterController {
* @param editParam 编辑参数
* @return Result<Object>
*/
@PostMapping("/edit")
@PutMapping("/{id}")
public Result<Object> edit(Integer id, @Validated @RequestBody SysPosterParam editParam) {
sysPosterService.edit(id, editParam);
return Result.success();
@ -77,7 +85,7 @@ public class SysPosterController {
* @param id 参数
* @return Result<Object>
*/
@PostMapping("/del")
@DeleteMapping("/{id}")
public Result<Object> del(@Validated @RequestBody Integer id) {
sysPosterService.del(id);
return Result.success();
@ -91,6 +99,51 @@ public class SysPosterController {
*/
@GetMapping("/type")
public Result<Object> type(@RequestParam(defaultValue = "") String type) {
if (type.isEmpty()) {
return Result.success(PosterTypeEnum.getType());
}
return Result.success(PosterTypeEnum.getType(type));
}
/**
* 自定义海报初始化数据
*
* @return
*/
@GetMapping("/init")
public Result init(SysPosterInitParam param) {
return Result.success(sysPosterService.init(param));
}
/**
* 海报模板
*
* @return
*/
@GetMapping("/template")
public Result template(SysPosterTemplateSearchParam param) {
return Result.success(sysPosterService.template(param));
}
/**
* 修改自定义海报状态
*
* @return
*/
@PutMapping("/status")
public Result modifyStatus(@RequestBody SysPosterModifyParam param) {
sysPosterService.modifyStatus(param.getId(), param.getStatus());
return Result.success();
}
/**
* 将自定义海报修改为默认海报
*
* @return
*/
@PutMapping("/default")
public Result modifyDefault(@RequestBody SysPosterModifyParam param) {
sysPosterService.modifyDefault(param.getId());
return Result.success();
}
}

View File

@ -36,10 +36,7 @@ public class SysVerifyController {
@GetMapping("/check_verifier")
public Result<?> checkVerifier(SysVerifyCheckVerifierParam param) {
boolean result = sysVerifyService.checkVerifier(param);
if (result) {
return Result.success();
}
return Result.fail();
return Result.success(result);
}
/**

View File

@ -1,54 +0,0 @@
package com.niu.core.entity.dict;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.niu.core.common.domain.BeanJsonSerializer;
import lombok.Data;
import java.io.Serializable;
/**
* 字典数据实体
*/
@Data
public class DictData implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
/** 类型 */
private Integer typeId;
/** 键名 */
private String name;
/** 数值 */
private String value;
/** 备注 */
private String remark;
/** 排序 */
private Integer sort;
/** 状态: 0=停用, 1=正常 */
private Integer status;
/** 是否删除: 0=否, 1=是 */
private Integer isDelete;
/** 创建时间 */
@JsonSerialize(using = BeanJsonSerializer.LongDateToStringSerializer.class)
private Long createTime;
/** 更新时间 */
private Long updateTime;
/** 删除时间 */
private Long deleteTime;
}

View File

@ -1,45 +0,0 @@
package com.niu.core.entity.dict;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 字典类型实体
*/
@Data
public class DictType implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId(value="id", type= IdType.AUTO)
private Integer id;
/** 字典名称 */
private String dictName;
/** 字典类型 */
private String dictType;
/** 字典备注 */
private String dictRemark;
/** 字典状态: 0=停用, 1=正常 */
private Integer dictStatus;
/** 是否删除: 0=否, 1=是 */
private Integer isDelete;
/** 创建时间 */
private Long createTime;
/** 更新时间 */
private Long updateTime;
/** 删除时间 */
private Long deleteTime;
}

View File

@ -2,41 +2,89 @@ package com.niu.core.entity.generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* 代码生成表字段信息表
* 代码生成器字段
*/
@Data
public class GenerateColumn implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
/**id*/
@TableId(value="id", type= IdType.AUTO)
private Integer id;
/**表id*/
private Integer tableId;
/**字段名称*/
private String columnName;
/**字段描述*/
private String columnComment;
/**字段类型*/
private String columnType;
/**是否必填 0-非必填 1-必填*/
private Integer isRequired;
/**是否主键 0-非主键 1-主键 */
private Integer isPk;
/**是否为插入字段 0-非自增 1-自增*/
private Integer isInsert;
/**是否为更新字段 0-不是 1-是*/
private Integer isUpdate;
/**是否为列表字段 0-不是 1-是*/
private Integer isLists;
/**是否为查询字段 0-不是 1-是*/
private Integer isQuery;
/**是否搜索字段*/
private Integer isSearch;
/**查询类型*/
private String queryType;
/**显示类型*/
private String viewType;
/**字典类型*/
private String dictType;
/**远程下拉关联应用*/
private String addon;
/**远程下拉关联model*/
private String model;
/**远程下拉标题字段*/
private String labelKey;
/**远程下拉value字段*/
private String valueKey;
/**创建时间*/
private Long createTime;
/**修改时间*/
private Long updateTime;
/**是否为软删除字段 0-不是 1-是*/
private Integer isDelete;
/**是否为排序字段 0-不是 1-是*/
private Integer isOrder;
/**验证类型*/
private String validateType;
}

View File

@ -2,29 +2,53 @@ package com.niu.core.entity.generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* 代码生成
* 代码生成
*/
@Data
public class GenerateTable implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
/**主键*/
@TableId(value="id", type= IdType.AUTO)
private Integer id;
/**表名*/
private String tableName;
/**表描述*/
private String tableContent;
/**模块名*/
private String moduleName;
/**类名前缀*/
private String className;
/**添加时间*/
private Long createTime;
/**编辑方式1-弹框 2-新页面*/
private Integer editType;
/**插件名*/
private String addonName;
/**排序方式 0-无排序 1-正序 2-倒序*/
private Integer orderType;
/**上级菜单*/
private String parentMenu;
/**关联配置*/
private String relations;
/**同步次数*/
private Integer synchronousNumber;
}

View File

@ -0,0 +1,56 @@
package com.niu.core.entity.sys;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 数据字典
*/
@Data
public class SysDict implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer Id;
/**
* 字典名称
*/
private String name;
/**
* 字典关键字
*/
@TableField(value = "`key`")
private String key;
/**
* 字典json
*/
private String dictionary;
/**
* 字典简介
*/
@TableField(value = "`memo`")
private String memo;
/**
* 添加时间
*/
private Long createTime;
/**
* 最后修改时间
*/
private Long updateTime;
}

View File

@ -0,0 +1,32 @@
package com.niu.core.enums.generator;
import com.niu.core.enums.site.SiteStatusEnum;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
@Getter
@AllArgsConstructor
public enum SqlColumnEnum {
STR("String", new String[]{"char", "varchar", "nvarchar", "varchar2","datetime", "time", "date", "text", "longText"}),
LONG("Long", new String[]{"timestamp"}),
INT("Integer", new String[]{"tinyint", "smallint", "mediumint", "int", "number", "integer", "bit", "bigint"}),
COMMISSION("BigDecimal", new String[]{"float", "double", "decimal"}),
GROWTH("Boolean", new String[]{"bool", "boolean"});
private final String field;
private final String[] columns;
public static Map<String, String[]> getMap() {
Map<String, String[]> map = new HashMap<>();
for(SqlColumnEnum item : SqlColumnEnum.values())
{
map.put(item.getField(), item.getColumns());
}
return map;
}
}

View File

@ -0,0 +1,15 @@
package com.niu.core.enums.poster;
import lombok.Getter;
@Getter
public enum PosterStatusEnum {
ON("1"),
OFF("2");
private final String status;
PosterStatusEnum(String status) {
this.status = status;
}
}

View File

@ -9,11 +9,18 @@ import java.util.stream.Collectors;
public class PosterTypeEnum {
public static JSONArray getType(String type){
JSONArray posterType = JsonModuleLoader.build().mergeResultSet("poster/type.json");
if (!type.isEmpty()) {
return JSONUtil.parseArray(posterType.toList(JSONObject.class).stream().filter(i -> i.getStr("type").equals(type)));
public static JSONArray getType(){
return JsonModuleLoader.build().mergeResultSet("poster/type.json");
}
public static JSONObject getType(String type){
JSONArray posterType = getType();
if (posterType.size() > 0) {
for (int i = 0; i < posterType.size(); i++) {
JSONObject item = posterType.getJSONObject(i);
if (item.getStr("type", "").equals(type)) return item;
}
}
return posterType;
return null;
}
}

View File

@ -0,0 +1,23 @@
package com.niu.core.event.sys;
import com.niu.core.common.component.context.event.Event;
import com.niu.core.common.component.context.event.EventResult;
import com.niu.core.common.component.context.listener.CallbackListener;
import lombok.Data;
/**
* 获取海报数据
*/
public abstract class GetPosterDataEventDefiner extends CallbackListener<GetPosterDataEventDefiner.GetPosterDataEvent> {
@Data
public static class GetPosterDataEvent extends Event {
private String type;
}
@Data
public static class GetPosterDataResult extends EventResult {
}
public abstract GetPosterDataEventDefiner.GetPosterDataResult handleCallback(GetPosterDataEventDefiner.GetPosterDataEvent event);
}

View File

@ -1,6 +1,7 @@
package com.niu.core.listener.member;
import com.niu.core.common.annotation.EventListen;
import com.niu.core.common.component.context.SpringContext;
import com.niu.core.common.component.context.listener.AbstractListener;
import com.niu.core.enums.member.AccountTypeEnum;
import com.niu.core.event.member.MemberAccountEvent;
@ -13,12 +14,10 @@ import javax.annotation.Resource;
@Component
public class MemberAccountListener extends AbstractListener {
@Resource
ICoreMemberLevelService coreMemberLevelService;
public void handleEvent(MemberAccountEvent event) {
// 会员升级检测
if (event.getAccountType().equals(AccountTypeEnum.GROWTH.getType())) {
ICoreMemberLevelService coreMemberLevelService = SpringContext.bean(ICoreMemberLevelService.class);
coreMemberLevelService.checkLevelUpgrade(event.getSiteId(), event.getMemberId());
}
}

View File

@ -8,6 +8,9 @@ import com.niu.core.service.admin.member.param.MemberAccountLogParam;
import com.niu.core.service.core.member.ICoreMemberService;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@EventListen("core")
@Component
public class MemberRegisterListener extends AbstractListener {
@ -17,13 +20,13 @@ public class MemberRegisterListener extends AbstractListener {
ICoreMemberService coreMemberService = (ICoreMemberService) SpringContext.getBean(ICoreMemberService.class);
// 注册发放成长值
MemberAccountLogParam sendGrowthParam = new MemberAccountLogParam();
sendGrowthParam.setFromType("member_register");
Map<String, Object> sendGrowthParam = new HashMap<>();
sendGrowthParam.put("from_type", "member_register");
coreMemberService.sendGrowth(event.getSiteId(), event.getMember().getMemberId(), "member_register", sendGrowthParam);
// 注册发放积分
MemberAccountLogParam sendPointParam = new MemberAccountLogParam();
sendPointParam.setFromType("member_register");
Map<String, Object> sendPointParam = new HashMap<>();
sendPointParam.put("from_type", "member_register");
coreMemberService.sendPoint(event.getSiteId(), event.getMember().getMemberId(), "member_register", sendPointParam);
}
}

View File

@ -1,12 +0,0 @@
package com.niu.core.mapper.dict;
import com.github.yulichang.base.MPJBaseMapper;
import com.niu.core.entity.dict.DictData;
import org.apache.ibatis.annotations.Mapper;
/**
* 字典数据 Mapper
*/
@Mapper
public interface DictDataMapper extends MPJBaseMapper<DictData> {
}

View File

@ -1,12 +0,0 @@
package com.niu.core.mapper.dict;
import com.github.yulichang.base.MPJBaseMapper;
import com.niu.core.entity.dict.DictType;
import org.apache.ibatis.annotations.Mapper;
/**
* 字典类型Mapper
*/
@Mapper
public interface DictTypeMapper extends MPJBaseMapper<DictType> {
}

View File

@ -0,0 +1,12 @@
package com.niu.core.mapper.generator;
import com.github.yulichang.base.MPJBaseMapper;
import com.niu.core.entity.generator.GenerateColumn;
import org.apache.ibatis.annotations.Mapper;
/**
* 代码生成字段信息Mapper
*/
@Mapper
public interface GenerateColumnMapper extends MPJBaseMapper<GenerateColumn> {
}

View File

@ -0,0 +1,12 @@
package com.niu.core.mapper.generator;
import com.github.yulichang.base.MPJBaseMapper;
import com.niu.core.entity.generator.GenerateTable;
import org.apache.ibatis.annotations.Mapper;
/**
* 代码生成Mapper
*/
@Mapper
public interface GenerateTableMapper extends MPJBaseMapper<GenerateTable> {
}

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.niu.core.mapper.member.MemberAccountLogMapper">
<select id="sumAccountData" parameterType="java.util.Map" resultType="java.lang.Double">
select
ABS(SUM(mal.account_data))
from
ns_member_account_log mal
<where>
<if test="site_id != null">
AND mal.site_id = #{site_id}
</if>
<if test="member_id != null">
AND mal.member_id = #{member_id}
</if>
<if test="account_type != null">
AND mal.account_type = #{account_type}
</if>
<if test="account_data != null">
AND mal.account_data &lt; #{account_data}
</if>
</where>
</select>
</mapper>

View File

@ -0,0 +1,15 @@
package com.niu.core.mapper.sys;
import com.github.yulichang.base.MPJBaseMapper;
import com.niu.core.entity.sys.SysDict;
import org.apache.ibatis.annotations.Mapper;
/**
* 数据字典 Mapper
*/
@Mapper
public interface SysDictMapper extends MPJBaseMapper<SysDict> {
}

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.niu.core.mapper.sys.SysUserMapper">
<!-- 开启二级缓存 -->
<!--
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
-->
<!-- 通用查询映射结果 -->
<resultMap id="baseResultMap" type="com.niu.core.entity.sys.SysUser">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="mobile" property="mobile"/>
<result column="email" property="email"/>
</resultMap>
<select id="selectSysUser" parameterType="java.util.Map" resultMap="baseResultMap">
select
*
from
`nc_sys_user` t
<where>
<if test="username != null">
AND t.username = ${username}
</if>
<if test="realName != null">
AND t.real_name = ${realName}
</if>
</where>
</select>
</mapper>

View File

@ -15,10 +15,13 @@ import com.niu.core.entity.sys.SysMenu;
import com.niu.core.mapper.sys.SysMenuMapper;
import com.niu.core.service.admin.addon.IAddonDevelopBuildService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.*;
import java.nio.file.*;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -138,15 +141,18 @@ public class AddonDevelopBuildServiceImpl implements IAddonDevelopBuildService {
FileTools.createDirs(destPath.getPath());
}
FileUtils.copyDirectory(sourcePath, destPath);
String[] exclusionDir = {".mvm", "target"};
FileUtils.copyDirectory(sourcePath, destPath, FileTools.createExclusionFilter(exclusionDir));
} catch (IOException e) {
throw new CommonException(e.getMessage());
}
}
private void jar() {
File sourcePath = new File(WebAppEnvs.get().projectNiucloudAddon + this.addon + "/target/" + this.addon + ".jar");
if (!sourcePath.exists()) throw new CommonException("请先通过maven打包好jar包");
try {
File sourcePath = new File(WebAppEnvs.get().projectNiucloudAddon + this.addon + "/target/" + this.addon + ".jar");
File destPath = new File(this.addonPath + "jar/");
if (destPath.exists()) {
FileUtils.cleanDirectory(destPath);

View File

@ -32,9 +32,7 @@ public class ConfigServiceImpl implements IConfigService {
public LoginConfigVo getLoginConfig() {
Integer defaultSiteId= RequestUtils.defaultSiteId();
JSONObject sysConfig=coreConfigService.getConfigValue(defaultSiteId, ConfigKeyEnum.ADMIN_LOGIN.getName());
LoginConfigVo vo = new LoginConfigVo();
BeanUtils.copyProperties(sysConfig, vo);
return vo;
return JSONUtil.toBean(sysConfig, LoginConfigVo.class);
}
/**

View File

@ -1,41 +0,0 @@
package com.niu.core.service.admin.dict;
import com.niu.core.service.admin.dict.param.DictDataParam;
import com.niu.core.service.admin.dict.vo.DictDataInfoVo;
/**
* 字典数据服务接口类
*/
public interface IDictDataService {
/**
* 字典数据详情
*
* @param id 主键ID
* @return DictDataInfoVo
*/
DictDataInfoVo info(Integer id);
/**
* 字典数据添加
*
* @param addParam 参数
*/
void add(DictDataParam addParam);
/**
* 字典数据编辑
*
* @param id 参数
* @param editParam 参数
*/
void edit(Integer id, DictDataParam editParam);
/**
* 字典数据删除
*
* @param id 主键ID
*/
void del(Integer id);
}

View File

@ -0,0 +1,77 @@
package com.niu.core.service.admin.dict;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.service.admin.dict.param.DictDataParam;
import com.niu.core.service.admin.dict.param.DictParam;
import com.niu.core.service.admin.dict.param.DictSearchParam;
import com.niu.core.service.admin.dict.vo.DictInfoVo;
import com.niu.core.service.admin.dict.vo.DictListVo;
import java.util.List;
/**
* 字典数据服务接口类
*/
public interface IDictService {
/**
* 字典列表
* @param pageParam
* @param searchParam
* @return
*/
PageResult<DictListVo> getPage(PageParam pageParam, DictSearchParam searchParam);
/**
* 字典数据详情
* @param id 主键ID
* @return DictInfoVo
*/
DictInfoVo info(Integer id);
/**
* 字典数据详情
* @param key 关键字
* @return DictInfoVo
*/
DictInfoVo info(String key);
/**
* 字典数据添加
* @param addParam 参数
*/
void add(DictParam addParam);
/**
* 字典数据编辑
* @param id 参数
* @param editParam 参数
*/
void edit(Integer id, DictParam editParam);
/**
* 添加字典数据
* @param id
* @param dictDataParam
*/
void addDictData(Integer id, DictDataParam dictDataParam);
/**
* 字典数据删除
*
* @param id 主键ID
*/
void del(Integer id);
/**
* 所有字典列表
* @return
*/
List<DictListVo> getAll();
}

View File

@ -1,112 +0,0 @@
package com.niu.core.service.admin.dict.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.niu.core.service.admin.dict.param.DictDataParam;
import com.niu.core.service.admin.dict.vo.DictDataInfoVo;
import com.niu.core.entity.dict.DictData;
import com.niu.core.mapper.dict.DictDataMapper;
import com.niu.core.service.admin.dict.IDictDataService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
/**
* 字典数据实现类
*/
@Service
public class DictDataServiceImpl implements IDictDataService {
@Resource
DictDataMapper dictDataMapper;
/**
* 字典数据详情
*
* @param id 主键参数
* @return DictData
*/
@Override
public DictDataInfoVo info(Integer id) {
DictData model = dictDataMapper.selectOne(
new QueryWrapper<DictData>()
.eq("id", id)
.eq("is_delete", 0)
.last("limit 1"));
Assert.notNull(model, "数据不存在");
DictDataInfoVo vo = new DictDataInfoVo();
BeanUtils.copyProperties(model, vo);
return vo;
}
/**
* 字典数据新增
*
* @param addParam 参数
*/
@Override
public void add(DictDataParam addParam) {
DictData model = new DictData();
model.setTypeId(addParam.getTypeId());
model.setName(addParam.getName());
model.setValue(addParam.getValue());
model.setRemark(addParam.getRemark());
model.setSort(addParam.getSort());
model.setStatus(addParam.getStatus());
model.setCreateTime(System.currentTimeMillis() / 1000);
model.setUpdateTime(System.currentTimeMillis() / 1000);
dictDataMapper.insert(model);
}
/**
* 字典数据编辑
*
* @param editParam 参数
*/
@Override
public void edit(Integer id, DictDataParam editParam) {
DictData model = dictDataMapper.selectOne(
new QueryWrapper<DictData>()
.eq("id", id)
.eq("is_delete", 0)
.last("limit 1"));
Assert.notNull(model, "数据不存在!");
model.setId(id);
model.setTypeId(editParam.getTypeId());
model.setName(editParam.getName());
model.setValue(editParam.getValue());
model.setRemark(editParam.getRemark());
model.setSort(editParam.getSort());
model.setStatus(editParam.getStatus());
model.setUpdateTime(System.currentTimeMillis() / 1000);
dictDataMapper.updateById(model);
}
/**
* 字典数据删除
*
* @param id 主键ID
*/
@Override
public void del(Integer id) {
DictData model = dictDataMapper.selectOne(
new QueryWrapper<DictData>()
.eq("id", id)
.eq("is_delete", 0)
.last("limit 1"));
Assert.notNull(model, "数据不存在!");
model.setIsDelete(1);
model.setDeleteTime(System.currentTimeMillis() / 1000);
dictDataMapper.updateById(model);
}
}

View File

@ -0,0 +1,181 @@
package com.niu.core.service.admin.dict.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.entity.sys.SysDict;
import com.niu.core.mapper.sys.SysDictMapper;
import com.niu.core.service.admin.dict.IDictService;
import com.niu.core.service.admin.dict.param.DictDataParam;
import com.niu.core.service.admin.dict.param.DictParam;
import com.niu.core.service.admin.dict.param.DictSearchParam;
import com.niu.core.service.admin.dict.vo.DictInfoVo;
import com.niu.core.service.admin.dict.vo.DictListVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
/**
* 字典数据实现类
*/
@Service
public class DictServiceImpl implements IDictService {
@Resource
SysDictMapper dictMapper;
@Override
public PageResult<DictListVo> getPage(PageParam pageParam, DictSearchParam searchParam) {
Integer page = pageParam.getPage();
Integer limit =pageParam.getLimit();
QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
//查询条件判断组装
if (ObjectUtil.isNotEmpty(searchParam.getName())) {
queryWrapper.like("name", searchParam.getName());
}
if (ObjectUtil.isNotEmpty(searchParam.getKey())) {
queryWrapper.eq("key", searchParam.getKey());
}
queryWrapper.orderByDesc("id");
IPage<SysDict> iPage = dictMapper.selectPage(new Page<>(page, limit), queryWrapper);
List<DictListVo> list = new LinkedList<>();
for (SysDict item : iPage.getRecords()) {
DictListVo vo = new DictListVo();
BeanUtils.copyProperties(item, vo);
list.add(vo);
}
return PageResult.build(page, limit, iPage.getTotal()).setData(list);
}
/**
* 字典数据详情
*
* @param id 主键参数
* @return DictData
*/
@Override
public DictInfoVo info(Integer id) {
SysDict model = dictMapper.selectOne(
new QueryWrapper<SysDict>()
.eq("id", id)
.last("limit 1"));
Assert.notNull(model, "数据不存在");
DictInfoVo vo = new DictInfoVo();
BeanUtils.copyProperties(model, vo);
return vo;
}
@Override
public DictInfoVo info(String key) {
SysDict model = dictMapper.selectOne(
new QueryWrapper<SysDict>()
.eq("key", key)
.last("limit 1"));
Assert.notNull(model, "数据不存在");
DictInfoVo vo = new DictInfoVo();
BeanUtils.copyProperties(model, vo);
return vo;
}
/**
* 字典数据新增
*
* @param addParam 参数
*/
@Override
public void add(DictParam addParam) {
SysDict model = new SysDict();
model.setName(addParam.getName());
model.setKey(addParam.getKey());
model.setMemo(addParam.getMemo());
model.setDictionary("[]");
model.setCreateTime(System.currentTimeMillis() / 1000);
model.setUpdateTime(System.currentTimeMillis() / 1000);
dictMapper.insert(model);
}
/**
* 字典数据编辑
*
* @param editParam 参数
*/
@Override
public void edit(Integer id, DictParam editParam) {
SysDict model = dictMapper.selectOne(
new QueryWrapper<SysDict>()
.eq("id", id)
.last("limit 1"));
Assert.notNull(model, "数据不存在!");
model.setId(id);
model.setName(editParam.getName());
model.setKey(editParam.getKey());
model.setMemo(editParam.getMemo());
model.setUpdateTime(System.currentTimeMillis() / 1000);
dictMapper.updateById(model);
}
@Override
public void addDictData(Integer id, DictDataParam dictDataParam)
{
SysDict model = dictMapper.selectOne(
new QueryWrapper<SysDict>()
.eq("id", id)
.last("limit 1"));
model.setDictionary(dictDataParam.getDictionary());
dictMapper.updateById(model);
}
/**
* 字典数据删除
*
* @param id 主键ID
*/
@Override
public void del(Integer id) {
SysDict model = dictMapper.selectOne(
new QueryWrapper<SysDict>()
.eq("id", id)
.last("limit 1"));
Assert.notNull(model, "数据不存在!");
dictMapper.deleteById(model);
}
@Override
public List<DictListVo> getAll() {
QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("id");
List<SysDict> voList = dictMapper.selectList(queryWrapper);
List<DictListVo> list = new LinkedList<>();
for (SysDict item : voList) {
DictListVo vo = new DictListVo();
BeanUtils.copyProperties(item, vo);
list.add(vo);
}
return list;
}
}

View File

@ -13,22 +13,9 @@ public class DictDataParam implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull(message = "typeId参数缺失")
private Integer typeId;
@NotNull(message = "name参数缺失")
private String name;
@NotNull(message = "字典数据不能为空")
private String dictionary;
@NotNull(message = "value参数缺失")
private String value;
@NotNull(message = "remark参数缺失")
private String remark;
@NotNull(message = "sort参数缺失")
private Integer sort;
@NotNull(message = "status参数缺失")
private Integer status;
}

View File

@ -0,0 +1,31 @@
package com.niu.core.service.admin.dict.param;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 字典数据参数
*/
@Data
public class DictParam implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull(message = "字典名称不能为空")
private String name;
@NotNull(message = "字典关键字不能为空")
private String key;
private String dictionary;
/**
* 字典简介
*/
private String memo = "";
}

View File

@ -8,20 +8,12 @@ import java.io.Serializable;
* 字典数据参数
*/
@Data
public class DictDataSearchParam implements Serializable {
public class DictSearchParam implements Serializable {
private static final long serialVersionUID = 1L;
private Integer typeId;
private String name;
private String value;
private String remark;
private Integer sort;
private Integer status;
private String key;
}

View File

@ -1,23 +0,0 @@
package com.niu.core.service.admin.dict.vo;
import lombok.Data;
import java.io.Serializable;
/**
* DictDataVo
*/
@Data
public class DictDataInfoVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 主键
private Integer typeId; // 类型
private String name; // 键名
private String value; // 数值
private String remark; // 备注
private Integer sort; // 排序
private Integer status; // 状态: 0=停用, 1=正常
}

View File

@ -1,25 +0,0 @@
package com.niu.core.service.admin.dict.vo;
import lombok.Data;
import java.io.Serializable;
/**
* DictDataVo
*/
@Data
public class DictDataListVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 主键
private Integer typeId; // 类型
private String name; // 键名
private String value; // 数值
private String remark; // 备注
private Integer sort; // 排序
private Integer status; // 状态: 0=停用, 1=正常
private String createTime; // 创建时间
private String updateTime; // 更新时间
}

View File

@ -0,0 +1,55 @@
package com.niu.core.service.admin.dict.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.niu.core.common.domain.BeanJsonSerializer;
import lombok.Data;
import java.io.Serializable;
/**
* 数据字典
*/
@Data
public class DictInfoVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Integer Id;
/**
* 字典名称
*/
private String name;
/**
* 字典关键字
*/
private String key;
/**
* 字典json
*/
@JsonSerialize(using = BeanJsonSerializer.StringToJsonSerializer.class)
private String dictionary;
/**
* 字典简介
*/
private String memo;
/**
* 添加时间
*/
@JsonSerialize(using = BeanJsonSerializer.LongDateToStringSerializer.class)
private Long createTime;
/**
* 最后修改时间
*/
@JsonSerialize(using = BeanJsonSerializer.LongDateToStringSerializer.class)
private Long updateTime;
}

View File

@ -0,0 +1,58 @@
package com.niu.core.service.admin.dict.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.niu.core.common.domain.BeanJsonSerializer;
import lombok.Data;
import java.io.Serializable;
/**
* 数据字典
*/
@Data
public class DictListVo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
private Integer Id;
/**
* 字典名称
*/
private String name;
/**
* 字典关键字
*/
private String key;
/**
* 字典json
*/
@JsonSerialize(using = BeanJsonSerializer.StringToJsonSerializer.class)
private String dictionary;
/**
* 字典简介
*/
private String memo;
/**
* 添加时间
*/
@JsonSerialize(using = BeanJsonSerializer.LongDateToStringSerializer.class)
private Long createTime;
/**
* 最后修改时间
*/
@JsonSerialize(using = BeanJsonSerializer.LongDateToStringSerializer.class)
private Long updateTime;
}

View File

@ -1,21 +0,0 @@
package com.niu.core.service.admin.dict.vo;
import lombok.Data;
import java.io.Serializable;
/**
* DictTypeVo
*/
@Data
public class DictTypeInfoVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 主键
private String dictName; // 字典名称
private String dictType; // 字典类型
private String dictRemark; // 字典备注
private Integer dictStatus; // 字典状态: 0=停用, 1=正常
}

View File

@ -1,23 +0,0 @@
package com.niu.core.service.admin.dict.vo;
import lombok.Data;
import java.io.Serializable;
/**
* DictTypeVo
*/
@Data
public class DictTypeListVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id; // 主键
private String dictName; // 字典名称
private String dictType; // 字典类型
private String dictRemark; // 字典备注
private Integer dictStatus; // 字典状态: 0=停用, 1=正常
private String createTime; // 创建时间
private String updateTime; // 更新时间
}

View File

@ -345,9 +345,10 @@ public class DiyServiceImpl implements IDiyService {
JSONObject pages = PagesEnum.getPagesByAddon(type, addon);
if (pages == null || pages.keySet().size() == 0) return null;
JSONObject data = new JSONObject();
String template = pages.keySet().iterator().next();
JSONObject data = pages.getJSONObject(template);
data.set("type", type);
data.set("template", pages.getJSONObject(pages.keySet().iterator().next()));
data.set("template", template);
return data;
}

View File

@ -0,0 +1,14 @@
package com.niu.core.service.admin.generator;
import com.niu.core.entity.generator.GenerateColumn;
import java.util.List;
/**
* 商品规格服务接口
*/
public interface IGenerateColumnService {
void insertAll(List<GenerateColumn> list);
}

View File

@ -0,0 +1,117 @@
package com.niu.core.service.admin.generator;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.service.admin.generator.param.GenerateCodeParam;
import com.niu.core.service.admin.generator.param.GenerateEditParam;
import com.niu.core.service.admin.generator.param.GenerateParam;
import com.niu.core.service.admin.generator.param.GenerateSearchParam;
import com.niu.core.service.admin.generator.vo.*;
import com.niu.core.service.core.generator.vo.CoreGenerateTemplateVo;
import java.io.File;
import java.util.List;
import java.util.Map;
/**
* 代码生成器接口服务类
*/
public interface IGenerateService {
PageResult<GenerateListVo> getPage(PageParam pageParam, GenerateSearchParam searchParam);
/**
* 代码生成详情
*
* @param id 主键ID
* @return GenerateDetailVo
*/
GenerateDetailVo getInfo(Integer id);
/**
* 代码生成新增
*
* @param generateParam 参数
*/
Integer add(GenerateParam generateParam);
/**
* 代码生成器编辑
* @param id
* @param generateParam
*/
void edit(Integer id, GenerateEditParam generateParam);
/**
* 代码生成删除
* @param id 主键ID
*/
void del(Integer id);
/**
* 生成代码包
* @param generateCodeParam
* @return
*/
void generate(GenerateCodeParam generateCodeParam);
/**
* 预览
* @param id
*/
List<GeneratePreviewVo> preview(Integer id);
/**
* 获取字段类型
* @param type
* @return
*/
String getDbFieldType(String type);
/**
* 获取数据表字段类型
* @param type
* @return
*/
String getDbType(String type);
/**
* 数据表列表
* @param name
* @param comment
* @return
*/
List<Map<String, Object>> tableList(String name, String comment);
/**
* 检测文件存在性
* @param checkFile
* @return
*/
Integer checkFile(String checkFile);
/**
* 获取表字段
* @param tableName
* @return
*/
List<TableFiledVo> getTableColumn(String tableName);
/**
* 获取模型
* @return
*/
List<String> getModels();
/**
* 获取表字段
* @param model
* @return
*/
TableFiledVo getModelColumn(String model);
}

View File

@ -0,0 +1,22 @@
package com.niu.core.service.admin.generator.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.niu.core.entity.generator.GenerateColumn;
import com.niu.core.mapper.generator.GenerateColumnMapper;
import com.niu.core.service.admin.generator.IGenerateColumnService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class GenerateColumnServiceImpl extends ServiceImpl<GenerateColumnMapper, GenerateColumn> implements IGenerateColumnService {
@Resource
GenerateColumnMapper generateColumnMapper;
@Override
public void insertAll(List<GenerateColumn> list) {
super.saveOrUpdateBatch(list);
}
}

View File

@ -0,0 +1,499 @@
package com.niu.core.service.admin.generator.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.github.yulichang.query.MPJQueryWrapper;
import com.niu.core.common.component.context.WebAppEnvs;
import com.niu.core.common.config.GlobalConfig;
import com.niu.core.common.domain.PageParam;
import com.niu.core.common.domain.PageResult;
import com.niu.core.common.exception.AdminException;
import com.niu.core.common.exception.CommonException;
import com.niu.core.common.utils.RequestUtils;
import com.niu.core.common.utils.file.FileTools;
import com.niu.core.entity.generator.GenerateColumn;
import com.niu.core.entity.generator.GenerateTable;
import com.niu.core.entity.site.Site;
import com.niu.core.entity.site.SiteGroup;
import com.niu.core.entity.sys.SysUserRole;
import com.niu.core.enums.generator.SqlColumnEnum;
import com.niu.core.mapper.generator.GenerateColumnMapper;
import com.niu.core.mapper.generator.GenerateTableMapper;
import com.niu.core.service.admin.generator.IGenerateColumnService;
import com.niu.core.service.admin.generator.IGenerateService;
import com.niu.core.service.admin.generator.param.GenerateCodeParam;
import com.niu.core.service.admin.generator.param.GenerateEditParam;
import com.niu.core.service.admin.generator.param.GenerateParam;
import com.niu.core.service.admin.generator.param.GenerateSearchParam;
import com.niu.core.service.admin.generator.vo.*;
import com.niu.core.service.admin.site.vo.SiteAdminVo;
import com.niu.core.service.admin.site.vo.SiteListVo;
import com.niu.core.service.core.app.tools.SQLScriptRunnerTools;
import com.niu.core.service.core.generator.CoreGenerateService;
import com.niu.core.service.core.generator.vo.CoreGenerateColumnVo;
import com.niu.core.service.core.generator.vo.CoreGenerateTemplateVo;
import com.qiniu.storage.ApiUploadV2AbortUpload;
import org.apache.commons.io.IOUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@Service
public class GenerateServiceImpl implements IGenerateService {
@Resource
private GenerateTableMapper generateTableMapper;
@Resource
private GenerateColumnMapper generateColumnMapper;
@Autowired
private JdbcTemplate jdbcTemplate;
@Resource
private IGenerateColumnService generateColumnService;
@Override
public PageResult<GenerateListVo> getPage(PageParam pageParam, GenerateSearchParam searchParam) {
Integer page = pageParam.getPage();
Integer limit =pageParam.getLimit();
MPJQueryWrapper<GenerateTable> queryWrapper = new MPJQueryWrapper<>();
queryWrapper.setAlias("ngt");
queryWrapper.select("ngt.id, ngt.table_name, ngt.table_content, ngt.module_name, ngt.class_name, ngt.create_time, ngt.edit_type, ngt.addon_name, ngt.order_type, ngt.parent_menu, ngt.relations, ngt.synchronous_number, na.title, na.`key`");
queryWrapper.leftJoin("?_addon na ON na.`key` = ngt.addon_name".replace("?_", GlobalConfig.tablePrefix));
if (ObjectUtil.isNotEmpty(searchParam.getTableName())) {
queryWrapper.like("ngt.table_name", searchParam.getTableName());
}
if (ObjectUtil.isNotEmpty(searchParam.getTableContent())) {
queryWrapper.eq("ngt.table_content", searchParam.getTableContent());
}
if (ObjectUtil.isNotEmpty(searchParam.getAddonName())) {
if(searchParam.getAddonName().equals("2"))
{
queryWrapper.eq("ngt.addon_name", "");
}else{
queryWrapper.like("ngt.addon_name", searchParam.getAddonName());
}
}
queryWrapper.orderByDesc("ngt.create_time");
IPage<GenerateListVo> iPage = generateTableMapper.selectJoinPage(new Page<>(page, limit),GenerateListVo.class, queryWrapper);
return PageResult.build(iPage);
}
@Override
public GenerateDetailVo getInfo(Integer id) {
GenerateTable generateTable = generateTableMapper.selectById(id);
if(ObjectUtil.isEmpty(generateTable)) throw new AdminException("生成表不存在");
GenerateDetailVo vo = new GenerateDetailVo();
BeanUtils.copyProperties(generateTable, vo);
if(vo.getOrderType() != 0)
{
GenerateColumn orderColumn = generateColumnMapper.selectOne(new QueryWrapper<GenerateColumn>().eq("table_id", id).eq("is_order", 1));
if(ObjectUtil.isNotEmpty(orderColumn))
{
vo.setOrderColumnName(orderColumn.getColumnName());
}else{
vo.setOrderColumnName("");
}
}
GenerateColumn deleteColumn = generateColumnMapper.selectOne(new QueryWrapper<GenerateColumn>().eq("table_id", id).eq("is_delete", 1));
if(ObjectUtil.isNotEmpty(deleteColumn))
{
vo.setDeleteColumnName(deleteColumn.getColumnName());
vo.setIsDelete(1);
}else{
vo.setDeleteColumnName("");
vo.setIsDelete(0);
}
List<GenerateColumn> columnList = generateColumnMapper.selectList(new QueryWrapper<GenerateColumn>().eq("table_id", id));
if( ObjectUtil.isNotEmpty(columnList))
{
List<GenerateColumnVo> columnVoList = new ArrayList<>();
for (GenerateColumn column : columnList) {
GenerateColumnVo generateColumnVo = new GenerateColumnVo();
BeanUtils.copyProperties(column, generateColumnVo);
if(column.getViewType().equals("number"))
{
if(!column.getValidateType().isEmpty())
{
if (column.getValidateType().startsWith("[")) {
JSONArray numValidate = JSONUtil.parseArray(column.getValidateType());
if(numValidate.get(0).toString().equals("between"))
{
generateColumnVo.setViewMax(JSONUtil.parseArray(numValidate.get(1)).get(1).toString());
generateColumnVo.setViewMin(JSONUtil.parseArray(numValidate.get(1)).get(0).toString());
}else if(numValidate.get(0).toString().equals("max"))
{
generateColumnVo.setViewMax(JSONUtil.parseArray(numValidate.get(1)).get(0).toString());
}else if(numValidate.get(0).toString().equals("min"))
{
generateColumnVo.setViewMin(JSONUtil.parseArray(numValidate.get(1)).get(0).toString());
}else{
generateColumnVo.setViewMax("100");
generateColumnVo.setViewMin("0");
}
}else{
generateColumnVo.setViewMax("100");
generateColumnVo.setViewMin("0");
}
}else{
generateColumnVo.setViewMax("100");
generateColumnVo.setViewMin("0");
}
}else{
generateColumnVo.setViewMax("");
generateColumnVo.setViewMin("");
}
if(!column.getValidateType().isEmpty())
{
if (column.getValidateType().startsWith("[")) {
JSONArray num1Validate = JSONUtil.parseArray(column.getValidateType());
if(num1Validate.get(0).toString().equals("between"))
{
generateColumnVo.setMaxNumber(JSONUtil.parseArray(num1Validate.get(1)).get(1).toString());
generateColumnVo.setMinNumber(JSONUtil.parseArray(num1Validate.get(1)).get(0).toString());
}else if(num1Validate.get(0).toString().equals("max"))
{
generateColumnVo.setMaxNumber(JSONUtil.parseArray(num1Validate.get(1)).get(0).toString());
}else if(num1Validate.get(0).toString().equals("min"))
{
generateColumnVo.setMinNumber(JSONUtil.parseArray(num1Validate.get(1)).get(0).toString());
}else{
generateColumnVo.setMaxNumber("120");
generateColumnVo.setMinNumber("1");
}
}else{
generateColumnVo.setMaxNumber("120");
generateColumnVo.setMinNumber("1");
}
}else{
generateColumnVo.setMaxNumber("120");
generateColumnVo.setMinNumber("1");
}
if(!column.getModel().isEmpty())
{
generateColumnVo.setSelectType(2);
}else{
generateColumnVo.setSelectType(1);
}
columnVoList.add(generateColumnVo);
}
vo.setTableColumn(columnVoList);
}
return vo;
}
@Override
@Transactional
public Integer add(GenerateParam generateParam) {
String sql = "SHOW TABLE STATUS WHERE 1=1 ";
String tablePrefix = GlobalConfig.tablePrefix;
if(!generateParam.getTableName().isEmpty()){
sql += " AND Name = '" + generateParam.getTableName() + "'";
}
List<Map<String, Object>> listData = jdbcTemplate.queryForList(sql);
if(ObjectUtil.isEmpty(listData)) throw new AdminException("数据表不存在");
Map<String, Object> table = listData.get(0);
if(ObjectUtil.isEmpty(table)) throw new AdminException("数据表不存在");
String tableName = table.get("Name").toString().substring(tablePrefix.length());
//添加生成表数据
GenerateTable generateTable = new GenerateTable();
generateTable.setTableName(tableName);
generateTable.setTableContent(table.get("Comment").toString());
generateTable.setClassName(tableName);
generateTable.setCreateTime(System.currentTimeMillis() / 1000);
generateTable.setModuleName(tableName);
generateTableMapper.insert(generateTable);
//添加生成字段数据
List<Map<String, Object>> columns = jdbcTemplate.queryForList("SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = (SELECT DATABASE()) and TABLE_NAME='" + tablePrefix + tableName+"'");
Integer id = generateTable.getId();
List<GenerateColumn> list = new ArrayList<>();
for (Map<String, Object> column : columns) {
GenerateColumn generateColumn = new GenerateColumn();
generateColumn.setIsRequired(0);
String[] defaultColumn = {"id", "create_time", "update_time"};
if(column.get("IS_NULLABLE").toString().equals("NO")&& !column.get("COLUMN_KEY").equals("PRI") && Arrays.asList(defaultColumn).contains(column.get("COLUMN_NAME").toString())){
generateColumn.setIsRequired(1);
}
generateColumn.setTableId(id);
generateColumn.setColumnName(column.get("COLUMN_NAME").toString());
generateColumn.setColumnType(getDbFieldType(column.get("DATA_TYPE").toString()));
if(generateColumn.getColumnType().equals("Integer") && generateColumn.getColumnName().contains("time")){
generateColumn.setColumnType("Long");
}
generateColumn.setColumnComment(column.get("COLUMN_COMMENT").toString());
generateColumn.setIsPk(column.get("COLUMN_KEY").equals("PRI")?1:0);
generateColumn.setIsInsert(Arrays.asList(defaultColumn).contains(column.get("COLUMN_NAME").toString())?0:1);
generateColumn.setIsUpdate(Arrays.asList(defaultColumn).contains(column.get("COLUMN_NAME").toString())?0:1);
generateColumn.setIsLists(Arrays.asList(defaultColumn).contains(column.get("COLUMN_NAME").toString())?0:1);
generateColumn.setIsDelete(0);
generateColumn.setQueryType("=");
generateColumn.setViewType("input");
generateColumn.setDictType("");
generateColumn.setAddon("");
generateColumn.setModel("");
generateColumn.setLabelKey("");
generateColumn.setValueKey("");
generateColumn.setCreateTime(System.currentTimeMillis() / 1000);
generateColumn.setUpdateTime(System.currentTimeMillis() / 1000);
list.add(generateColumn);
}
generateColumnService.insertAll(list);
return id;
}
@Override
@Transactional
public void edit(Integer id, GenerateEditParam generateParam) {
//添加生成表数据
GenerateTable generateTable = new GenerateTable();
generateTable.setId(id);
generateTable.setTableName(generateParam.getTableName());
generateTable.setTableContent(generateParam.getTableContent());
generateTable.setModuleName(generateParam.getModuleName());
generateTable.setClassName(generateParam.getClassName());
generateTable.setEditType(generateParam.getEditType());
generateTable.setAddonName(generateParam.getAddonName());
generateTable.setOrderType(generateParam.getOrderType());
generateTable.setParentMenu(generateParam.getParentMenu());
generateTable.setRelations(generateParam.getRelations());
generateTableMapper.updateById(generateTable);
//更新表字段
generateColumnMapper.delete(new QueryWrapper<GenerateColumn>().eq("table_id", id));
JSONArray columns = JSONUtil.parseArray(generateParam.getTableColumn());
List<GenerateColumn> list = new ArrayList<>();
for(int i = 0; i < columns.size(); i++){
GenerateColumn generateColumn = new GenerateColumn();
JSONObject column = columns.getJSONObject(i);
generateColumn.setTableId(id);
generateColumn.setColumnName(column.getStr("column_name"));
generateColumn.setColumnComment(column.getStr("column_comment"));
generateColumn.setIsPk(column.getInt("is_pk"));
generateColumn.setIsRequired(column.getInt("is_required"));
generateColumn.setIsInsert(column.getInt("is_insert"));
generateColumn.setIsUpdate(column.getInt("is_update"));
generateColumn.setIsLists(column.getInt("is_lists"));
generateColumn.setIsSearch(column.getInt("is_search"));
generateColumn.setIsDelete(0);
generateColumn.setIsOrder(0);
generateColumn.setQueryType(column.getStr("query_type"));
generateColumn.setViewType(ObjectUtil.isEmpty(column.getStr("view_type")) ? "input" : column.getStr("view_type"));
generateColumn.setDictType(ObjectUtil.isEmpty(column.getStr("dict_type")) ? "" : column.getStr("dict_type"));
generateColumn.setAddon(ObjectUtil.isEmpty(column.getStr("addon")) ? "" : column.getStr("addon"));
generateColumn.setModel(ObjectUtil.isEmpty(column.getStr("model")) ? "" : column.getStr("model"));
generateColumn.setLabelKey(ObjectUtil.isEmpty(column.getStr("label_key")) ? "" : column.getStr("label_key"));
generateColumn.setValueKey(ObjectUtil.isEmpty(column.getStr("value_key")) ? "" : column.getStr("value_key"));
generateColumn.setUpdateTime(System.currentTimeMillis() / 1000);
generateColumn.setCreateTime(System.currentTimeMillis() / 1000);
generateColumn.setColumnType(ObjectUtil.isEmpty(column.getStr("column_type")) ? "String" : column.getStr("column_type"));
generateColumn.setValidateType(ObjectUtil.isEmpty(column.getStr("validate_type")) ? "" : column.getStr("validate_type"));
//传入字段rule暂时不知含义待定
if(generateParam.getIsDelete() == 1)
{
if(column.getStr("column_name").equals(generateParam.getDeleteColumnName()))
{
generateColumn.setIsDelete(1);
}
}
if(generateParam.getOrderType() != 0)
{
if(column.getStr("column_name").equals(generateParam.getOrderColumnName()))
{
generateColumn.setIsOrder(1);
}
}
if(ObjectUtil.isNotEmpty(column.getStr("validate_type")) && !column.getStr("view_type").equals("number")) {
if (column.getStr("validate_type").equals("between")) {
JSONArray jsonArray = new JSONArray();
jsonArray.add("between");
jsonArray.add(new String[]{column.getStr("min_number"), column.getStr("max_number")});
generateColumn.setValidateType(jsonArray.toString());
} else if (column.getStr("validate_type").equals("max")) {
JSONArray jsonArray = new JSONArray();
jsonArray.add("max");
jsonArray.add(new String[]{column.getStr("max_number")});
generateColumn.setValidateType(jsonArray.toString());
} else if (column.getStr("validate_type").equals("min")) {
JSONArray jsonArray = new JSONArray();
jsonArray.add("min");
jsonArray.add(new String[]{column.getStr("min_number")});
generateColumn.setValidateType(jsonArray.toString());
}
}
if(column.getStr("view_type").equals("number")){
JSONArray numJsonArray = new JSONArray();
numJsonArray.add("between");
numJsonArray.add(new String[]{column.getStr("view_min"), column.getStr("view_max")});
generateColumn.setValidateType(numJsonArray.toString());
}
if(ObjectUtil.isNotEmpty(column.getStr("model")))
{
generateColumn.setDictType("");
}
list.add(generateColumn);
}
generateColumnService.insertAll(list);
}
@Override
@Transactional
public void del(Integer id) {
generateTableMapper.deleteById(id);
generateColumnMapper.delete(new QueryWrapper<GenerateColumn>().eq("table_id", id));
}
@Override
public void generate(GenerateCodeParam generateCodeParam) {
GenerateTable generateTable = generateTableMapper.selectById(generateCodeParam.getId());
List<GenerateColumn> columnList = generateColumnMapper.selectList(new QueryWrapper<GenerateColumn>().eq("table_id", generateCodeParam.getId()));
CoreGenerateService coreGenerateService = new CoreGenerateService();
List<CoreGenerateTemplateVo> list =coreGenerateService.generateCode(generateTable, columnList);
// 下载
if (generateCodeParam.getGenerateType().equals("2")) {
String tempDir = WebAppEnvs.get().webRootDownResource + "upload/generate/";
String packageDir = tempDir + "package/";
FileTools.createDirs(packageDir);
FileUtil.clean(tempDir);
for (CoreGenerateTemplateVo coreGenerateTemplateVo : list) {
FileTools.createDirs(packageDir + coreGenerateTemplateVo.getPath());
FileUtil.writeUtf8String(coreGenerateTemplateVo.getData(), new File(packageDir + coreGenerateTemplateVo.getPath(), coreGenerateTemplateVo.getFileName()));
}
File zipFile = ZipUtil.zip(packageDir, tempDir + "package.zip");
} else {
// 同步
if (!WebAppEnvs.get().envType.equals("dev")) throw new CommonException("只有在开发模式下才能进行同步代码");
for (CoreGenerateTemplateVo coreGenerateTemplateVo : list) {
if (coreGenerateTemplateVo.getType().equals("sql")) {
SQLScriptRunnerTools.execScript(coreGenerateTemplateVo.getData());
} else {
FileUtil.writeUtf8String(coreGenerateTemplateVo.getData(), new File(WebAppEnvs.get().projectRoot + "/" + coreGenerateTemplateVo.getPath(), coreGenerateTemplateVo.getFileName()));
}
}
}
}
@Override
public List<GeneratePreviewVo> preview(Integer id) {
GenerateTable generateTable = generateTableMapper.selectById(id);
List<GenerateColumn> list = generateColumnMapper.selectList(new QueryWrapper<GenerateColumn>().eq("table_id", id));
CoreGenerateService coreGenerateService = new CoreGenerateService();
List<CoreGenerateTemplateVo> columnList =coreGenerateService.generateCode(generateTable, list);
List<GeneratePreviewVo> voList = new ArrayList<>();
for (CoreGenerateTemplateVo coreGenerateTemplateVo : columnList) {
GeneratePreviewVo vo = new GeneratePreviewVo();
vo.setName(coreGenerateTemplateVo.getFileName());
vo.setType(coreGenerateTemplateVo.getType());
vo.setContent(coreGenerateTemplateVo.getData());
vo.setFileDir(coreGenerateTemplateVo.getPath() + "/");
voList.add(vo);
}
return voList;
}
@Override
public String getDbFieldType(String type) {
type = getDbType(type);
Map<String, String[]> map = SqlColumnEnum.getMap();
String field = "";
for (Map.Entry<String, String[]> entry : map.entrySet()) {
if (Arrays.asList(entry.getValue()).contains(type)) {
field = entry.getKey();
}
}
if(field.equals("")){
field = "String";
}
return field;
}
@Override
public String getDbType(String columnType) {
if (StrUtil.contains(columnType, "(")) {
return StrUtil.subAfter(columnType, "(", true);
}
else {
return columnType;
}
}
@Override
public List<Map<String, Object>> tableList(String name, String comment) {
String sql = "SHOW TABLE STATUS WHERE 1=1 ";
if(!(name == null)){
sql += " AND Name like '%" + name + "%'";
}
if(!(comment == null)){
sql += " AND comment like '%" + comment + "%'";
}
List<Map<String, Object>> listData = jdbcTemplate.queryForList(sql);
return listData;
}
@Override
public Integer checkFile(String checkFile) {
return null;
}
@Override
public List<TableFiledVo> getTableColumn(String tableName) {
return null;
}
@Override
public List<String> getModels() {
return null;
}
@Override
public TableFiledVo getModelColumn(String model) {
return null;
}
}

View File

@ -0,0 +1,20 @@
package com.niu.core.service.admin.generator.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 代码生成创建
*/
@Data
public class GenerateCodeParam implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String generateType;
}

View File

@ -0,0 +1,61 @@
package com.niu.core.service.admin.generator.param;
import cn.hutool.json.JSONArray;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 代码生成创建
*/
@Data
public class GenerateEditParam implements Serializable {
private static final long serialVersionUID = 1L;
/**表名*/
private String tableName;
/**表描述*/
private String tableContent;
/**模块名*/
private String moduleName;
/**类名前缀*/
private String className;
/**添加时间*/
private Long createTime;
/**编辑方式1-弹框 2-新页面*/
private Integer editType = 1;
/**插件名*/
private String addonName;
/**排序方式 0-无排序 1-正序 2-倒序*/
private Integer orderType = 0;
private String orderColumnName = "";
/**上级菜单*/
private String parentMenu = "";
/**关联配置*/
private String relations = "";
/**同步次数*/
private Integer synchronousNumber;
private Integer isDelete = 0;
private String deleteColumnName = "";
private String tableColumn;
}

View File

@ -0,0 +1,16 @@
package com.niu.core.service.admin.generator.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 代码生成创建
*/
@Data
public class GenerateParam implements Serializable {
private static final long serialVersionUID = 1L;
private String tableName;
}

View File

@ -0,0 +1,24 @@
package com.niu.core.service.admin.generator.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 代码生成创建
*/
@Data
public class GenerateSearchParam implements Serializable {
private static final long serialVersionUID = 1L;
private String tableName;
private String tableContent;
private String moduleName;
private String addonName;
}

View File

@ -0,0 +1,100 @@
package com.niu.core.service.admin.generator.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 代码生成器字段
*/
@Data
public class GenerateColumnVo implements Serializable {
private static final long serialVersionUID = 1L;
/**id*/
@TableId(value="id", type= IdType.AUTO)
private Integer id;
/**表id*/
private Integer tableId;
/**字段名称*/
private String columnName;
/**字段描述*/
private String columnComment;
/**字段类型*/
private String columnType;
/**是否必填 0-非必填 1-必填*/
private Integer isRequired;
/**是否主键 0-非主键 1-主键 */
private Integer isPk;
/**是否为插入字段 0-非自增 1-自增*/
private Integer isInsert;
/**是否为更新字段 0-不是 1-是*/
private Integer isUpdate;
/**是否为列表字段 0-不是 1-是*/
private Integer isLists;
/**是否为查询字段 0-不是 1-是*/
private Integer isQuery;
/**是否搜索字段*/
private Integer isSearch;
/**查询类型*/
private String queryType;
/**显示类型*/
private String viewType;
/**字典类型*/
private String dictType;
/**远程下拉关联应用*/
private String addon;
/**远程下拉关联model*/
private String model;
/**远程下拉标题字段*/
private String labelKey;
/**远程下拉value字段*/
private String valueKey;
/**创建时间*/
private Long createTime;
/**修改时间*/
private Long updateTime;
/**是否为软删除字段 0-不是 1-是*/
private Integer isDelete;
/**是否为排序字段 0-不是 1-是*/
private Integer isOrder;
/**验证类型*/
private String validateType;
private String viewMax;
private String viewMin;
private String maxNumber;
private String minNumber;
private Integer selectType;
}

View File

@ -0,0 +1,62 @@
package com.niu.core.service.admin.generator.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.niu.core.common.domain.BeanJsonSerializer;
import com.niu.core.entity.generator.GenerateColumn;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class GenerateDetailVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
/**表名*/
private String tableName;
/**表描述*/
private String tableContent;
/**模块名*/
private String moduleName;
/**类名前缀*/
private String className;
/**添加时间*/
private Long createTime;
/**编辑方式1-弹框 2-新页面*/
private Integer editType;
/**插件名*/
private String addonName;
/**排序方式 0-无排序 1-正序 2-倒序*/
private Integer orderType;
private String orderColumnName;
/**上级菜单*/
private String parentMenu;
/**关联配置*/
@JsonSerialize(using = BeanJsonSerializer.StringToJsonSerializer.class)
private String relations;
/**同步次数*/
private Integer synchronousNumber;
private Integer isDelete;
private String deleteColumnName;
private List<GenerateColumnVo> tableColumn;
}

View File

@ -0,0 +1,54 @@
package com.niu.core.service.admin.generator.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.niu.core.common.domain.BeanJsonSerializer;
import lombok.Data;
import java.io.Serializable;
@Data
public class GenerateListVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
/**表名*/
private String tableName;
/**表描述*/
private String tableContent;
/**模块名*/
private String moduleName;
/**类名前缀*/
private String className;
/**添加时间*/
@JsonSerialize(using = BeanJsonSerializer.LongDateToStringSerializer.class)
private Long createTime;
/**编辑方式1-弹框 2-新页面*/
private Integer editType;
/**插件名key*/
private String addonName;
/**排序方式 0-无排序 1-正序 2-倒序*/
private Integer orderType;
/**上级菜单*/
private String parentMenu;
/**关联配置*/
private String relations;
/**同步次数*/
private Integer synchronousNumber;
/**插件名称*/
private String title;
}

View File

@ -0,0 +1,22 @@
package com.niu.core.service.admin.generator.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.niu.core.common.domain.BeanJsonSerializer;
import lombok.Data;
import java.io.Serializable;
@Data
public class GeneratePreviewVo implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String type;
private String content;
private String fileDir;
}

View File

@ -0,0 +1,48 @@
package com.niu.core.service.admin.generator.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class TableFiledVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
/**表名*/
private String tableName;
/**表描述*/
private String tableContent;
/**模块名*/
private String moduleName;
/**类名前缀*/
private String className;
/**添加时间*/
private Long createTime;
/**编辑方式1-弹框 2-新页面*/
private Integer editType;
/**插件名*/
private String addonName;
/**排序方式 0-无排序 1-正序 2-倒序*/
private Integer orderType;
/**上级菜单*/
private String parentMenu;
/**关联配置*/
private String relations;
/**同步次数*/
private Integer synchronousNumber;
}

View File

@ -0,0 +1,48 @@
package com.niu.core.service.admin.generator.vo;
import lombok.Data;
import java.io.Serializable;
@Data
public class TableListVo implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
/**表名*/
private String tableName;
/**表描述*/
private String tableContent;
/**模块名*/
private String moduleName;
/**类名前缀*/
private String className;
/**添加时间*/
private Long createTime;
/**编辑方式1-弹框 2-新页面*/
private Integer editType;
/**插件名*/
private String addonName;
/**排序方式 0-无排序 1-正序 2-倒序*/
private Integer orderType;
/**上级菜单*/
private String parentMenu;
/**关联配置*/
private String relations;
/**同步次数*/
private Integer synchronousNumber;
}

View File

@ -172,10 +172,9 @@ public class MemberServiceImpl implements IMemberService {
addParam.setUsername(addParam.getMobile());
Member mobileIsExist = memberMapper.selectOne(new QueryWrapper<Member>()
.eq("mobile", addParam.getMobile())
.or()
.eq("username", addParam.getMobile())
.select("member_id")
.eq("site_id", siteId)
.and(i -> i.eq("mobile", addParam.getMobile()).or().eq("username", addParam.getMobile()))
.last("limit 1"));
Assert.isNull(mobileIsExist, "手机号已存在");
@ -183,14 +182,25 @@ public class MemberServiceImpl implements IMemberService {
addParam.setNickname(addParam.getMobile().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
}
if (addParam.getMemberNo().isEmpty()) {
addParam.setMemberNo(iCoreMemberService.createMemberNo(siteId));
} else {
Member memberNoIsExist = memberMapper.selectOne(new QueryWrapper<Member>()
.select("member_id")
.eq("site_id", siteId)
.eq("member_no", addParam.getMemberNo())
.last("limit 1"));
Assert.isNull(memberNoIsExist, "会员编码已存在");
}
Member model = new Member();
model.setSiteId(siteId);
model.setMobile(addParam.getMobile());
model.setMemberNo(addParam.getMemberNo());
model.setUsername(addParam.getUsername());
model.setNickname(addParam.getNickname());
model.setHeadimg(addParam.getHeadimg());
model.setPassword(addParam.getPassword());
model.setSex(addParam.getSex());
model.setBirthday(addParam.getBirthday());
model.setRegisterType(MemberRegisterTypeEnum.MANUAL.getType());
model.setRegisterChannel(MemberRegisterChannelEnum.MANUAL.getType());
model.setCreateTime(System.currentTimeMillis() / 1000);

View File

@ -17,9 +17,7 @@ public class MemberAddParam implements Serializable {
private String memberNo;
private Integer pid;
private Integer siteId;
private String initMemberNo;
private String username;
@ -37,81 +35,4 @@ public class MemberAddParam implements Serializable {
private String headimg;
private Integer memberLevel;
private String memberLabel;
private String wxOpenid;
private String weappOpenid;
private String wxUnionid;
private String aliOpenid;
private String douyinOpenid;
private String registerChannel;
private String registerType;
private String loginIp;
private String loginType;
private String loginChannel;
private Integer loginCount;
private Integer loginTime;
private Integer lastVisitTime;
private Integer lastConsumTime;
private Integer sex;
private Integer status;
private String birthday;
private Integer point;
private Integer pointGet;
private BigDecimal balance;
private BigDecimal balanceGet;
private BigDecimal money;
private BigDecimal moneyGet;
private BigDecimal moneyCashOuting;
private Integer growth;
private Integer growthGet;
private BigDecimal commission;
private BigDecimal commissionGet;
private BigDecimal commissionCashOuting;
private Integer isMember;
private Integer memberTime;
private Integer isDel;
private Integer provinceId;
private Integer cityId;
private Integer districtId;
private String address;
private String location;
}

View File

@ -238,19 +238,19 @@ public class CloudBuildServiceImpl implements ICloudBuildService {
if (uniApp.exists()) {
String[] exclusionDir = {"node_modules", "unpackage", "dist"};
FileTools.createDirs(packageDir + "uni-app");
FileUtils.copyDirectory(uniApp, new File(packageDir + "uni-app/"), createExclusionFilter(exclusionDir));
FileUtils.copyDirectory(uniApp, new File(packageDir + "uni-app/"), FileTools.createExclusionFilter(exclusionDir));
}
File admin = new File(rootDir + "admin/");
if (admin.exists()) {
String[] exclusionDir = {"node_modules", ".vscode", "dist", ".idea"};
FileTools.createDirs(packageDir + "admin");
FileUtils.copyDirectory(admin, new File(packageDir + "admin/"), createExclusionFilter(exclusionDir));
FileUtils.copyDirectory(admin, new File(packageDir + "admin/"), FileTools.createExclusionFilter(exclusionDir));
}
File web = new File(rootDir + "web/");
if (web.exists()) {
String[] exclusionDir = {"node_modules", ".output", "nuxt"};
String[] exclusionDir = {"node_modules", ".output", "nuxt", "dist", ".nuxt"};
FileTools.createDirs(packageDir + "web");
FileUtils.copyDirectory(web, new File(packageDir + "web/"), createExclusionFilter(exclusionDir));
FileUtils.copyDirectory(web, new File(packageDir + "web/"), FileTools.createExclusionFilter(exclusionDir));
}
// 打包自定义端口
@ -274,27 +274,6 @@ public class CloudBuildServiceImpl implements ICloudBuildService {
}
}
/**
* 排除目录
* @param dirs
* @return
*/
private static IOFileFilter createExclusionFilter(String[] dirs) {
// 定义要排除的目录
List<String> excludedDirs = Arrays.asList(dirs);
// 创建一个过滤器来排除特定子目录
IOFileFilter excludeSubDirsFilter = FileFilterUtils.trueFileFilter(); // 初始化为 false表示过滤所有文件或目录
// 循环创建过滤器
for (String dirName : excludedDirs) {
IOFileFilter tempFilter = FileFilterUtils.nameFileFilter(dirName);
excludeSubDirsFilter = FileFilterUtils.and(excludeSubDirsFilter, FileFilterUtils.notFileFilter(tempFilter));
}
return excludeSubDirsFilter;
}
/**
* 清除编译任务
*/

Some files were not shown because too many files have changed in this diff Show More