Browse Source

前端页面改造基本完成 待优化

main
piexlmax 3 years ago
parent
commit
2b3d36b598
  1. 4
      server/source/system/api.go
  2. 4
      server/source/system/casbin.go
  3. 62
      web/src/components/customPic/index.vue
  4. 64
      web/src/components/upload/image.vue
  5. 13
      web/src/components/warningBar/warningBar.vue
  6. 61
      web/src/mixins/infoList.js
  7. 11
      web/src/utils/format.js
  8. 52
      web/src/view/about/index.vue
  9. 53
      web/src/view/dashboard/dashboardCharts/echartsLine.vue
  10. 32
      web/src/view/dashboard/dashboardTable/dashboardTable.vue
  11. 36
      web/src/view/dashboard/index.vue
  12. 148
      web/src/view/example/breakpoint/breakpoint.vue
  13. 117
      web/src/view/example/customer/customer.vue
  14. 66
      web/src/view/example/excel/excel.vue
  15. 136
      web/src/view/example/upload/upload.vue
  16. 5
      web/src/view/superAdmin/menu/menu.vue
  17. 4
      web/src/view/superAdmin/operation/sysOperationRecord.vue
  18. 52
      web/src/view/system/state.vue
  19. 7
      web/src/view/systemTools/autoCode/component/previewCodeDialg.vue
  20. 2
      web/src/view/systemTools/system/system.vue

4
server/source/system/api.go

@ -59,6 +59,10 @@ func (a *api) Initialize() error {
{ApiGroup: "菜单", Method: "POST", Path: "/menu/getMenuAuthority", Description: "获取指定角色menu"}, {ApiGroup: "菜单", Method: "POST", Path: "/menu/getMenuAuthority", Description: "获取指定角色menu"},
{ApiGroup: "菜单", Method: "POST", Path: "/menu/addMenuAuthority", Description: "增加menu和角色关联关系"}, {ApiGroup: "菜单", Method: "POST", Path: "/menu/addMenuAuthority", Description: "增加menu和角色关联关系"},
{ApiGroup: "分片上传", Method: "POST", Path: "/fileUploadAndDownload/findFile", Description: "寻找目标文件(秒传)"},
{ApiGroup: "分片上传", Method: "POST", Path: "/fileUploadAndDownload/breakpointContinueFinish", Description: "断点续传"},
{ApiGroup: "分片上传", Method: "POST", Path: "/fileUploadAndDownload/removeChunk", Description: "上传完成"},
{ApiGroup: "文件上传与下载", Method: "POST", Path: "/fileUploadAndDownload/upload", Description: "文件上传示例"}, {ApiGroup: "文件上传与下载", Method: "POST", Path: "/fileUploadAndDownload/upload", Description: "文件上传示例"},
{ApiGroup: "文件上传与下载", Method: "POST", Path: "/fileUploadAndDownload/deleteFile", Description: "删除文件"}, {ApiGroup: "文件上传与下载", Method: "POST", Path: "/fileUploadAndDownload/deleteFile", Description: "删除文件"},
{ApiGroup: "文件上传与下载", Method: "POST", Path: "/fileUploadAndDownload/getFileList", Description: "获取上传文件列表"}, {ApiGroup: "文件上传与下载", Method: "POST", Path: "/fileUploadAndDownload/getFileList", Description: "获取上传文件列表"},

4
server/source/system/casbin.go

@ -54,6 +54,10 @@ func (c *casbin) Initialize() error {
{PType: "p", V0: "888", V1: "/user/setUserAuthority", V2: "POST"}, {PType: "p", V0: "888", V1: "/user/setUserAuthority", V2: "POST"},
{PType: "p", V0: "888", V1: "/user/setUserAuthorities", V2: "POST"}, {PType: "p", V0: "888", V1: "/user/setUserAuthorities", V2: "POST"},
{PType: "p", V0: "888", V1: "/fileUploadAndDownload/findFile", V2: "GET"},
{PType: "p", V0: "888", V1: "/fileUploadAndDownload/breakpointContinueFinish", V2: "POST"},
{PType: "p", V0: "888", V1: "/fileUploadAndDownload/removeChunk", V2: "POST"},
{PType: "p", V0: "888", V1: "/fileUploadAndDownload/upload", V2: "POST"}, {PType: "p", V0: "888", V1: "/fileUploadAndDownload/upload", V2: "POST"},
{PType: "p", V0: "888", V1: "/fileUploadAndDownload/deleteFile", V2: "POST"}, {PType: "p", V0: "888", V1: "/fileUploadAndDownload/deleteFile", V2: "POST"},
{PType: "p", V0: "888", V1: "/fileUploadAndDownload/getFileList", V2: "POST"}, {PType: "p", V0: "888", V1: "/fileUploadAndDownload/getFileList", V2: "POST"},

62
web/src/components/customPic/index.vue

@ -15,12 +15,18 @@
</template> </template>
<script> <script>
import noAvatar from '@/assets/noBody.png'
import { mapGetters } from 'vuex'
const path = import.meta.env.VITE_BASE_API
export default { export default {
name: 'CustomPic',
props: {
name: 'CustomPic'
}
</script>
<script setup>
import noAvatarPng from '@/assets/noBody.png'
import { useStore } from 'vuex'
import { computed, ref, defineProps } from 'vue-demi'
const store = useStore()
const props = defineProps({
picType: { picType: {
type: String, type: String,
required: false, required: false,
@ -31,36 +37,32 @@ export default {
required: false, required: false,
default: '' default: ''
} }
},
data() {
return {
noAvatar: noAvatar,
path: path + '/'
}
},
computed: {
...mapGetters('user', ['userInfo']),
avatar() {
if (this.picSrc === '') {
if (this.userInfo.headerImg !== '' && this.userInfo.headerImg.slice(0, 4) === 'http') {
return this.userInfo.headerImg
})
const path = ref(import.meta.env.VITE_BASE_API + '/')
const noAvatar = ref(noAvatarPng)
const userInfo = computed(() => store.getters['user/userInfo'])
const avatar = computed(() => {
if (props.picSrc === '') {
if (userInfo.value.headerImg !== '' && userInfo.value.headerImg.slice(0, 4) === 'http') {
return userInfo.value.headerImg
} }
return this.path + this.userInfo.headerImg
return path.value + userInfo.value.headerImg
} else { } else {
if (this.picSrc !== '' && this.picSrc.slice(0, 4) === 'http') {
return this.picSrc
if (props.picSrc !== '' && props.picSrc.slice(0, 4) === 'http') {
return props.picSrc
} }
return this.path + this.picSrc
}
},
file() {
if (this.picSrc && this.picSrc.slice(0, 4) !== 'http') {
return this.path + this.picSrc
return path.value + props.picSrc
} }
return this.picSrc
})
const file = computed(() => {
if (props.picSrc && props.picSrc.slice(0, 4) !== 'http') {
return path.value + props.picSrc
} }
}
}
return props.picSrc
})
</script> </script>
<style scoped> <style scoped>

64
web/src/components/upload/image.vue

@ -14,17 +14,15 @@
</div> </div>
</template> </template>
<script>
const path = import.meta.env.VITE_BASE_API
import { mapGetters } from 'vuex'
<script setup>
import ImageCompress from '@/utils/image' import ImageCompress from '@/utils/image'
export default {
name: 'UploadImage',
model: {
prop: 'imageUrl',
event: 'change'
},
props: {
import { computed, ref } from 'vue'
import { useStore } from 'vuex'
import { ElMessage } from 'element-plus'
const store = useStore()
const emit = defineEmits(['on-success'])
const props = defineProps({
imageUrl: { imageUrl: {
type: String, type: String,
default: '' default: ''
@ -37,43 +35,45 @@ export default {
type: Number, type: Number,
default: 1920 // default: 1920 //
} }
},
data() {
return {
path: path
}
},
computed: {
...mapGetters('user', ['userInfo', 'token']),
showImageUrl() {
return (this.imageUrl && this.imageUrl.slice(0, 4) !== 'http') ? path + this.imageUrl : this.imageUrl
}
},
methods: {
beforeImageUpload(file) {
})
const path = ref(import.meta.env.VITE_BASE_API)
const token = computed(()=>store.getters['user/token'])
const showImageUrl = computed(()=>(props.imageUrl && props.imageUrl.slice(0, 4) !== 'http') ? path.value + props.imageUrl : props.imageUrl)
const beforeImageUpload = (file) => {
const isJPG = file.type === 'image/jpeg' const isJPG = file.type === 'image/jpeg'
const isPng = file.type === 'image/png' const isPng = file.type === 'image/png'
if (!isJPG && !isPng) { if (!isJPG && !isPng) {
this.$message.error('上传头像图片只能是 jpg或png 格式!')
ElMessage.error('上传头像图片只能是 jpg或png 格式!')
return false return false
} }
const isRightSize = file.size / 1024 < this.fileSize
const isRightSize = file.size / 1024 < props.fileSize
if (!isRightSize) { if (!isRightSize) {
// //
const compress = new ImageCompress(file, this.fileSize, this.maxWH)
const compress = new ImageCompress(file, props.fileSize, props.maxWH)
return compress.compress() return compress.compress()
} }
return isRightSize return isRightSize
},
handleImageSuccess(res) {
// this.imageUrl = URL.createObjectURL(file.raw);
}
const handleImageSuccess = (res) => {
const { data } = res const { data } = res
if (data.file) { if (data.file) {
this.$emit('change', data.file.url)
this.$emit('on-success')
emit('on-success',data.file.url)
} }
} }
</script>
<script>
export default {
name: 'UploadImage',
methods: {
} }
} }
</script> </script>

13
web/src/components/warningBar/warningBar.vue

@ -10,20 +10,15 @@
</span> </span>
</div> </div>
</template> </template>
<script>
<script setup>
import { WarningFilled } from '@element-plus/icons' import { WarningFilled } from '@element-plus/icons'
export default {
components: {
[WarningFilled.name]: WarningFilled
},
props: {
import { defineProps } from 'vue'
defineProps({
title: { title: {
type: String, type: String,
default: '' default: ''
}, },
}
}
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.warning-bar{ .warning-bar{

61
web/src/mixins/infoList.js

@ -1,61 +0,0 @@
import { getDict } from '@/utils/dictionary'
import { formatTimeToStr } from '@/utils/date'
export default {
data() {
return {
page: 1,
total: 10,
pageSize: 10,
tableData: [],
searchInfo: {}
}
},
methods: {
formatBoolean: function(bool) {
if (bool !== null) {
return bool ? '是' : '否'
} else {
return ''
}
},
formatDate: function(time) {
if (time !== null && time !== '') {
var date = new Date(time)
return formatTimeToStr(date, 'yyyy-MM-dd hh:mm:ss')
} else {
return ''
}
},
filterDict(value, type) {
const rowLabel = this[type + 'Options'] && this[type + 'Options'].filter(item => item.value === value)
return rowLabel && rowLabel[0] && rowLabel[0].label
},
async getDict(type) {
const dicts = await getDict(type)
this[type + 'Options'] = dicts
return dicts
},
handleSizeChange(val) {
this.pageSize = val
this.getTableData()
},
handleCurrentChange(val) {
this.page = val
this.getTableData()
},
// @params beforeFunc function 请求发起前执行的函数 默认为空函数
// @params afterFunc function 请求完成后执行的函数 默认为空函数
async getTableData(beforeFunc = () => {}, afterFunc = () => {}) {
beforeFunc()
const table = await this.listApi({ page: this.page, pageSize: this.pageSize, ...this.searchInfo })
if (table.code === 0) {
this.tableData = table.data.list
this.total = table.data.total
this.page = table.data.page
this.pageSize = table.data.pageSize
}
afterFunc()
}
}
}

11
web/src/utils/format.js

@ -1,4 +1,5 @@
import { formatTimeToStr } from '@/utils/date' import { formatTimeToStr } from '@/utils/date'
import { getDict } from '@/utils/dictionary'
export const formatBoolean = (bool) => { export const formatBoolean = (bool) => {
if (bool !== null) { if (bool !== null) {
@ -15,3 +16,13 @@ export const formatDate = (time) => {
return '' return ''
} }
} }
export const filterDict = (value, options) => {
const rowLabel = options && options.filter(item => item.value === value)
return rowLabel && rowLabel[0] && rowLabel[0].label
}
export const getDictFunc = async(type) => {
const dicts = await getDict(type)
return dicts
}

52
web/src/view/about/index.vue

@ -108,31 +108,27 @@
</template> </template>
<script> <script>
import { Commits, Members } from '@/api/github'
export default { export default {
name: 'About', name: 'About',
data() {
return {
messageWhenNoItems: 'There arent commits',
members: [],
dataTimeline: [],
page: 0,
}
},
created() {
this.loadCommits()
this.loadMembers()
},
methods: {
loadMore() {
this.page++
this.loadCommits()
},
loadCommits() {
Commits(this.page).then(({ data }) => {
}
</script>
<script setup>
import { ref } from 'vue'
import { Commits, Members } from '@/api/github'
const members = ref([])
const dataTimeline = ref([])
const page = ref(0)
const loadMore = () => {
page.value++
loadCommits()
}
const loadCommits = () => {
Commits(page.value).then(({ data }) => {
data.forEach((element) => { data.forEach((element) => {
if (element.commit.message) { if (element.commit.message) {
this.dataTimeline.push({
dataTimeline.value.push({
from: new Date(element.commit.author.date), from: new Date(element.commit.author.date),
title: element.commit.author.name, title: element.commit.author.name,
showDayAndMonth: true, showDayAndMonth: true,
@ -141,15 +137,17 @@ export default {
} }
}) })
}) })
},
loadMembers() {
}
const loadMembers = () => {
Members().then(({ data }) => { Members().then(({ data }) => {
this.members = data
this.members.sort()
members.value = data
members.value.sort()
}) })
},
},
} }
loadCommits()
loadMembers()
</script> </script>
<style scoped> <style scoped>

53
web/src/view/dashboard/dashboardCharts/echartsLine.vue

@ -9,9 +9,9 @@
/> />
</div> </div>
</template> </template>
<script>
<script setup>
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { toRaw } from 'vue'
import { nextTick, onMounted, onUnmounted, ref } from 'vue'
import 'echarts/theme/macarons' import 'echarts/theme/macarons'
var dataAxis = [] var dataAxis = []
@ -40,32 +40,14 @@ for (var i = 0; i < data.length; i++) {
dataShadow.push(yMax) dataShadow.push(yMax)
} }
export default {
name: 'Line',
data() {
return {
chart: null,
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeUnmount() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.echart, 'macarons')
this.setOptions()
},
setOptions() {
toRaw(this.chart).setOption({
const chart = ref(null)
const echart = ref(null)
const initChart = () => {
chart.value = echarts.init(echart.value, 'macarons')
setOptions()
}
const setOptions = () => {
chart.value.setOption({
grid: { grid: {
left: '40', left: '40',
right: '20', right: '20',
@ -117,9 +99,20 @@ export default {
}, },
], ],
}) })
},
},
} }
onMounted(async() => {
await nextTick()
initChart()
})
onUnmounted(() => {
if (!chart.value) {
return
}
chart.value.dispose()
chart.value = null
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dashboard-line-box { .dashboard-line-box {

32
web/src/view/dashboard/dashboardTable/dashboardTable.vue

@ -14,25 +14,24 @@
</template> </template>
<script> <script>
export default {
name: 'DashboardTable',
}
</script>
<script setup>
import { Commits } from '@/api/github' import { Commits } from '@/api/github'
import { formatTimeToStr } from '@/utils/date.js' import { formatTimeToStr } from '@/utils/date.js'
export default {
data() {
return {
loading: true,
dataTimeline: [],
}
},
created() {
this.loadCommits()
},
methods: {
loadCommits() {
import { ref } from 'vue-demi'
const loading = ref(true)
const dataTimeline = ref([])
const loadCommits = () => {
Commits(0).then(({ data }) => { Commits(0).then(({ data }) => {
this.loading = false
loading.value = false
data.forEach((element, index) => { data.forEach((element, index) => {
if (element.commit.message && index < 10) { if (element.commit.message && index < 10) {
this.dataTimeline.push({
dataTimeline.value.push({
from: formatTimeToStr(element.commit.author.date, 'yyyy-MM-dd'), from: formatTimeToStr(element.commit.author.date, 'yyyy-MM-dd'),
title: element.commit.author.name, title: element.commit.author.name,
showDayAndMonth: true, showDayAndMonth: true,
@ -41,10 +40,11 @@ export default {
} }
}) })
}) })
},
}
} }
loadCommits()
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.commit-table{ .commit-table{
background-color: #fff; background-color: #fff;

36
web/src/view/dashboard/index.vue

@ -103,18 +103,14 @@
</div> </div>
</div> </div>
</template> </template>
<script>
<script setup>
import echartsLine from '@/view/dashboard/dashboardCharts/echartsLine.vue' import echartsLine from '@/view/dashboard/dashboardCharts/echartsLine.vue'
import dashboardTable from '@/view/dashboard/dashboardTable/dashboardTable.vue' import dashboardTable from '@/view/dashboard/dashboardTable/dashboardTable.vue'
export default {
name: 'Dashboard',
components: {
echartsLine,
dashboardTable
},
data() {
return {
toolCards: [
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const toolCards = ref([
{ {
label: '用户管理', label: '用户管理',
icon: 'monitor', icon: 'monitor',
@ -157,14 +153,18 @@ export default {
color: '#5cdbd3', color: '#5cdbd3',
bg: 'rgba(92, 219, 211,.3)' bg: 'rgba(92, 219, 211,.3)'
} }
]
}
},
methods: {
toTarget(name) {
this.$router.push({ name })
}
}
])
const router = useRouter()
const toTarget = (name) => {
router.push({ name })
}
</script>
<script>
export default {
name: 'Dashboard'
} }
</script> </script>

148
web/src/view/example/breakpoint/breakpoint.vue

@ -5,7 +5,7 @@
<form id="fromCont" method="post"> <form id="fromCont" method="post">
<div class="fileUpload" @click="inputChange"> <div class="fileUpload" @click="inputChange">
选择文件 选择文件
<input v-show="false" id="file" ref="Input" multiple="multiple" type="file" @change="choseFile">
<input v-show="false" id="file" ref="FileInput" multiple="multiple" type="file" @change="choseFile">
</div> </div>
</form> </form>
<el-button :disabled="limitFileSize" type="primary" size="mini" class="uploadBtn" @click="getFile">上传文件</el-button> <el-button :disabled="limitFileSize" type="primary" size="mini" class="uploadBtn" @click="getFile">上传文件</el-button>
@ -28,7 +28,7 @@
</template> </template>
<script>
<script setup>
import SparkMD5 from 'spark-md5' import SparkMD5 from 'spark-md5'
import axios from 'axios' import axios from 'axios'
import { import {
@ -36,59 +36,55 @@ import {
breakpointContinueFinish, breakpointContinueFinish,
removeChunk removeChunk
} from '@/api/breakpoint' } from '@/api/breakpoint'
export default {
name: 'BreakPoint',
data() {
return {
file: null,
fileMd5: '',
formDataList: [],
waitUpLoad: [],
waitNum: 0,
limitFileSize: false,
percentage: 0,
percentageFlage: true,
customColor: '#409eff'
}
},
methods: {
//
async choseFile(e) {
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const file = ref(null)
const fileMd5 = ref('')
const formDataList = ref([])
const waitUpLoad = ref([])
const waitNum = ref(0)
const limitFileSize = ref(false)
const percentage = ref(0)
const percentageFlage = ref(true)
//
const choseFile = async(e) => {
const fileR = new FileReader() // reader const fileR = new FileReader() // reader
const file = e.target.files[0] //
const fileInput = e.target.files[0] //
const maxSize = 5 * 1024 * 1024 const maxSize = 5 * 1024 * 1024
this.file = file // file 便 func
this.percentage = 0
if (file.size < maxSize) {
fileR.readAsArrayBuffer(file) // ArrayBuffer
file.value = fileInput // file 便 func
percentage.value = 0
if (file.value.size < maxSize) {
fileR.readAsArrayBuffer(file.value) // ArrayBuffer
fileR.onload = async e => { fileR.onload = async e => {
// arrayBuffer e dome e.target.result // arrayBuffer e dome e.target.result
const blob = e.target.result const blob = e.target.result
const spark = new SparkMD5.ArrayBuffer() // md5 md5 const spark = new SparkMD5.ArrayBuffer() // md5 md5
spark.append(blob) // spark.append(blob) //
this.fileMd5 = spark.end() // a md5
fileMd5.value = spark.end() // a md5
const FileSliceCap = 1 * 1024 * 1024 // const FileSliceCap = 1 * 1024 * 1024 //
let start = 0 // let start = 0 //
let end = 0 // a let end = 0 // a
let i = 0 // let i = 0 //
this.formDataList = [] //
while (end < file.size) {
formDataList.value = [] //
while (end < file.value.size) {
// size // size
start = i * FileSliceCap // start = i * FileSliceCap //
end = (i + 1) * FileSliceCap // end = (i + 1) * FileSliceCap //
var fileSlice = this.file.slice(start, end) // file.slice h5
var fileSlice = file.value.slice(start, end) // file.slice h5
const formData = new window.FormData() // FormData const formData = new window.FormData() // FormData
formData.append('fileMd5', this.fileMd5) // Md5
formData.append('fileMd5', fileMd5.value) // Md5
formData.append('file', fileSlice) // formData.append('file', fileSlice) //
formData.append('chunkNumber', i) // formData.append('chunkNumber', i) //
formData.append('fileName', this.file.name) // formData.appen formData
this.formDataList.push({ key: i, formData }) //
formData.append('fileName', file.value.name) // formData.appen formData
formDataList.value.push({ key: i, formData }) //
i++ i++
} }
const params = { const params = {
fileName: this.file.name,
fileMd5: this.fileMd5,
chunkTotal: this.formDataList.length
fileName: file.value.name,
fileMd5: fileMd5.value,
chunkTotal: formDataList.value.length
} }
const res = await findFile(params) const res = await findFile(params)
// //
@ -96,75 +92,93 @@ export default {
const IsFinish = res.data.file.IsFinish // md5 const IsFinish = res.data.file.IsFinish // md5
if (!IsFinish) { if (!IsFinish) {
// //
this.waitUpLoad = this.formDataList.filter(all => {
waitUpLoad.value = formDataList.value.filter(all => {
return !( return !(
finishList && finishList &&
finishList.some(fi => fi.FileChunkNumber === all.key) finishList.some(fi => fi.FileChunkNumber === all.key)
) // ) //
}) })
} else { } else {
this.waitUpLoad = [] //
waitUpLoad.value = [] //
} }
this.waitNum = this.waitUpLoad.length //
waitNum.value = waitUpLoad.value.length //
} }
} else { } else {
this.limitFileSize = true
this.$message('请上传小于5M文件')
limitFileSize.value = true
ElMessage('请上传小于5M文件')
} }
},
getFile() {
}
const getFile = () => {
// //
if (this.file === null) {
this.$message('请先上传文件')
if (file.value === null) {
ElMessage('请先上传文件')
return return
} }
this.percentage = Math.floor(((this.formDataList.length - this.waitNum) / this.formDataList.length) * 100)
if (this.percentage === 100) {
this.percentageFlage = false
percentage.value = Math.floor(((formDataList.value.length - waitNum.value) / formDataList.value.length) * 100)
if (percentage.value === 100) {
percentageFlage.value = false
} }
this.sliceFile() //
},
sliceFile() {
this.waitUpLoad &&
this.waitUpLoad.forEach(item => {
sliceFile() //
}
const sliceFile = () => {
waitUpLoad.value &&
waitUpLoad.value.forEach(item => {
// //
item.formData.append('chunkTotal', this.formDataList.length) //
item.formData.append('chunkTotal', formDataList.value.length) //
const fileR = new FileReader() // const fileR = new FileReader() //
const file = item.formData.get('file')
fileR.readAsArrayBuffer(file)
const fileF = item.formData.get('file')
fileR.readAsArrayBuffer(fileF)
fileR.onload = e => { fileR.onload = e => {
const spark = new SparkMD5.ArrayBuffer() const spark = new SparkMD5.ArrayBuffer()
spark.append(e.target.result) spark.append(e.target.result)
item.formData.append('chunkMd5', spark.end()) // md5 item.formData.append('chunkMd5', spark.end()) // md5
this.upLoadFileSlice(item)
upLoadFileSlice(item)
} }
}) })
},
async upLoadFileSlice(item) {
}
const upLoadFileSlice = async(item) => {
// //
await axios.post(import.meta.env.VITE_BASE_API + '/fileUploadAndDownload/breakpointContinue', item.formData) await axios.post(import.meta.env.VITE_BASE_API + '/fileUploadAndDownload/breakpointContinue', item.formData)
this.waitNum-- //
if (this.waitNum === 0) {
waitNum.value-- //
if (waitNum.value === 0) {
// //
const params = { const params = {
fileName: this.file.name,
fileMd5: this.fileMd5
fileName: file.value.name,
fileMd5: fileMd5.value
} }
const res = await breakpointContinueFinish(params) const res = await breakpointContinueFinish(params)
if (res.success) { if (res.success) {
// //
const params = { const params = {
fileName: this.file.name,
fileMd5: this.fileMd5,
fileName: file.value.name,
fileMd5: fileMd5.value,
filePath: res.data.filePath filePath: res.data.filePath
} }
await removeChunk(params) await removeChunk(params)
} }
} }
},
inputChange() {
this.$refs.Input.dispatchEvent(new MouseEvent('click'))
}
const FileInput = ref(null)
const inputChange = () => {
FileInput.value.dispatchEvent(new MouseEvent('click'))
}
</script>
<script>
export default {
name: 'BreakPoint',
data() {
return {
} }
},
methods: {
} }
} }
</script> </script>

117
web/src/view/example/customer/customer.vue

@ -68,7 +68,7 @@
</div> </div>
</template> </template>
<script>
<script setup>
import { import {
createExaCustomer, createExaCustomer,
updateExaCustomer, updateExaCustomer,
@ -76,82 +76,107 @@ import {
getExaCustomer, getExaCustomer,
getExaCustomerList getExaCustomerList
} from '@/api/customer' } from '@/api/customer'
import infoList from '@/mixins/infoList'
import warningBar from '@/components/warningBar/warningBar.vue' import warningBar from '@/components/warningBar/warningBar.vue'
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { formatDate } from '@/utils/format'
export default {
name: 'Customer',
components: { warningBar },
mixins: [infoList],
data() {
return {
listApi: getExaCustomerList,
dialogFormVisible: false,
type: '',
form: {
const dialogFormVisible = ref(false)
const type = ref('')
const form = ref({
customerName: '', customerName: '',
customerPhoneData: '' customerPhoneData: ''
})
const page = ref(1)
const total = ref(0)
const pageSize = ref(10)
const tableData = ref([])
//
const handleSizeChange = (val) => {
pageSize.value = val
getTableData()
}
const handleCurrentChange = (val) => {
page.value = val
getTableData()
}
//
const getTableData = async() => {
const table = await getExaCustomerList({ page: page.value, pageSize: pageSize.value })
if (table.code === 0) {
tableData.value = table.data.list
total.value = table.data.total
page.value = table.data.page
pageSize.value = table.data.pageSize
} }
}
},
created() {
this.getTableData()
},
methods: {
async updateCustomer(row) {
}
getTableData()
const updateCustomer = async(row) => {
const res = await getExaCustomer({ ID: row.ID }) const res = await getExaCustomer({ ID: row.ID })
this.type = 'update'
type.value = 'update'
if (res.code === 0) { if (res.code === 0) {
this.form = res.data.customer
this.dialogFormVisible = true
form.value = res.data.customer
dialogFormVisible.value = true
} }
},
closeDialog() {
this.dialogFormVisible = false
this.form = {
}
const closeDialog = () => {
dialogFormVisible.value = false
form.value = {
customerName: '', customerName: '',
customerPhoneData: '' customerPhoneData: ''
} }
},
async deleteCustomer(row) {
}
const deleteCustomer = async(row) => {
row.visible = false row.visible = false
const res = await deleteExaCustomer({ ID: row.ID }) const res = await deleteExaCustomer({ ID: row.ID })
if (res.code === 0) { if (res.code === 0) {
this.$message({
ElMessage({
type: 'success', type: 'success',
message: '删除成功' message: '删除成功'
}) })
if (this.tableData.length === 1 && this.page > 1) {
this.page--
if (tableData.value.length === 1 && page.value > 1) {
page.value--
} }
this.getTableData()
getTableData()
} }
},
async enterDialog() {
}
const enterDialog = async() => {
let res let res
switch (this.type) {
switch (type.value) {
case 'create': case 'create':
res = await createExaCustomer(this.form)
res = await createExaCustomer(form.value)
break break
case 'update': case 'update':
res = await updateExaCustomer(this.form)
res = await updateExaCustomer(form.value)
break break
default: default:
res = await createExaCustomer(this.form)
res = await createExaCustomer(form.value)
break break
} }
if (res.code === 0) { if (res.code === 0) {
this.closeDialog()
this.getTableData()
}
},
openDialog() {
this.type = 'create'
this.dialogFormVisible = true
}
closeDialog()
getTableData()
} }
} }
const openDialog = () => {
type.value = 'create'
dialogFormVisible.value = true
}
</script>
<script>
export default {
name: 'Customer'
}
</script> </script>
<style></style> <style></style>

66
web/src/view/example/excel/excel.vue

@ -34,43 +34,51 @@
</template> </template>
<script> <script>
const path = import.meta.env.VITE_BASE_API
import { mapGetters } from 'vuex'
import infoList from '@/mixins/infoList'
import { exportExcel, loadExcelData, downloadTemplate } from '@/api/excel'
import { getMenuList } from '@/api/menu'
export default { export default {
name: 'Excel', name: 'Excel',
mixins: [infoList],
data() {
return {
listApi: getMenuList,
path: path
}
</script>
<script setup>
import { useStore } from 'vuex'
import { exportExcel, loadExcelData, downloadTemplate } from '@/api/excel'
import { getMenuList } from '@/api/menu'
import { computed, ref } from 'vue'
const path = ref(import.meta.env.VITE_BASE_API)
const page = ref(1)
const total = ref(0)
const pageSize = ref(999)
const tableData = ref([])
//
const getTableData = async(f = () => {}) => {
const table = await f({ page: page.value, pageSize: pageSize.value })
if (table.code === 0) {
tableData.value = table.data.list
total.value = table.data.total
page.value = table.data.page
pageSize.value = table.data.pageSize
} }
},
computed: {
...mapGetters('user', ['userInfo', 'token'])
},
created() {
this.pageSize = 999
this.getTableData()
},
methods: {
handleExcelExport(fileName) {
}
getTableData(getMenuList)
const store = useStore()
const token = computed(() => store.getters['user/token'])
const handleExcelExport = (fileName) => {
if (!fileName || typeof fileName !== 'string') { if (!fileName || typeof fileName !== 'string') {
fileName = 'ExcelExport.xlsx' fileName = 'ExcelExport.xlsx'
} }
exportExcel(this.tableData, fileName)
},
loadExcel() {
this.listApi = loadExcelData
this.getTableData()
},
downloadExcelTemplate() {
exportExcel(tableData.value, fileName)
}
const loadExcel = () => {
getTableData(loadExcelData)
}
const downloadExcelTemplate = () => {
downloadTemplate('ExcelTemplate.xlsx') downloadTemplate('ExcelTemplate.xlsx')
}
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

136
web/src/view/example/upload/upload.vue

@ -14,7 +14,7 @@
<el-button size="mini" type="primary">普通上传</el-button> <el-button size="mini" type="primary">普通上传</el-button>
</el-upload> </el-upload>
<upload-image <upload-image
v-model="imageUrl"
v-model:imageUrl="imageUrl"
:file-size="512" :file-size="512"
:max-w-h="1080" :max-w-h="1080"
class="upload-btn" class="upload-btn"
@ -46,7 +46,7 @@
<el-table-column align="left" label="操作" width="160"> <el-table-column align="left" label="操作" width="160">
<template #default="scope"> <template #default="scope">
<el-button size="small" icon="download" type="text" @click="downloadFile(scope.row)">下载</el-button> <el-button size="small" icon="download" type="text" @click="downloadFile(scope.row)">下载</el-button>
<el-button size="small" icon="delete" type="text" @click="deleteFile(scope.row)">删除</el-button>
<el-button size="small" icon="delete" type="text" @click="deleteFileFunc(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -66,39 +66,55 @@
</div> </div>
</template> </template>
<script>
const path = import.meta.env.VITE_BASE_API
import { mapGetters } from 'vuex'
import infoList from '@/mixins/infoList'
<script setup>
import { useStore } from 'vuex'
import { getFileList, deleteFile } from '@/api/fileUploadAndDownload' import { getFileList, deleteFile } from '@/api/fileUploadAndDownload'
import { downloadImage } from '@/utils/downloadImg' import { downloadImage } from '@/utils/downloadImg'
import CustomPic from '@/components/customPic/index.vue' import CustomPic from '@/components/customPic/index.vue'
import UploadImage from '@/components/upload/image.vue' import UploadImage from '@/components/upload/image.vue'
export default {
name: 'Upload',
components: {
CustomPic,
UploadImage
},
mixins: [infoList],
data() {
return {
fullscreenLoading: false,
listApi: getFileList,
path: path,
tableData: [],
imageUrl: ''
import { formatDate } from '@/utils/format'
import { computed, ref } from 'vue-demi'
import { ElMessage, ElMessageBox } from 'element-plus'
const store = useStore()
const path = ref(import.meta.env.VITE_BASE_API)
const token = computed(() => store.getters['user/token'])
const fullscreenLoading = ref(false)
const imageUrl = ref('')
const page = ref(1)
const total = ref(0)
const pageSize = ref(10)
const tableData = ref([])
//
const handleSizeChange = (val) => {
pageSize.value = val
getTableData()
}
const handleCurrentChange = (val) => {
page.value = val
getTableData()
}
//
const getTableData = async() => {
const table = await getFileList({ page: page.value, pageSize: pageSize.value })
if (table.code === 0) {
tableData.value = table.data.list
total.value = table.data.total
page.value = table.data.page
pageSize.value = table.data.pageSize
} }
},
computed: {
...mapGetters('user', ['userInfo', 'token'])
},
created() {
this.getTableData()
},
methods: {
async deleteFile(row) {
this.$confirm('此操作将永久文件, 是否继续?', '提示', {
}
getTableData()
const deleteFileFunc = async(row) => {
ElMessageBox.confirm('此操作将永久文件, 是否继续?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
@ -106,71 +122,77 @@ export default {
.then(async() => { .then(async() => {
const res = await deleteFile(row) const res = await deleteFile(row)
if (res.code === 0) { if (res.code === 0) {
this.$message({
ElMessage({
type: 'success', type: 'success',
message: '删除成功!' message: '删除成功!'
}) })
if (this.tableData.length === 1 && this.page > 1) {
this.page--
if (tableData.value.length === 1 && page.value > 1) {
page.value--
} }
this.getTableData()
getTableData()
} }
}) })
.catch(() => { .catch(() => {
this.$message({
ElMessage({
type: 'info', type: 'info',
message: '已取消删除' message: '已取消删除'
}) })
}) })
},
checkFile(file) {
this.fullscreenLoading = true
}
const checkFile = (file) => {
fullscreenLoading.value = true
const isJPG = file.type === 'image/jpeg' const isJPG = file.type === 'image/jpeg'
const isPng = file.type === 'image/png' const isPng = file.type === 'image/png'
const isLt2M = file.size / 1024 / 1024 < 0.5 const isLt2M = file.size / 1024 / 1024 < 0.5
if (!isJPG && !isPng) { if (!isJPG && !isPng) {
this.$message.error('上传图片只能是 jpg或png 格式!')
this.fullscreenLoading = false
ElMessage.error('上传图片只能是 jpg或png 格式!')
fullscreenLoading.value = false
} }
if (!isLt2M) { if (!isLt2M) {
this.$message.error('未压缩未见上传图片大小不能超过 500KB,请使用压缩上传')
this.fullscreenLoading = false
ElMessage.error('未压缩未见上传图片大小不能超过 500KB,请使用压缩上传')
fullscreenLoading.value = false
} }
return (isPng || isJPG) && isLt2M return (isPng || isJPG) && isLt2M
},
uploadSuccess(res) {
this.fullscreenLoading = false
}
const uploadSuccess = (res) => {
fullscreenLoading.value = false
if (res.code === 0) { if (res.code === 0) {
this.$message({
ElMessage({
type: 'success', type: 'success',
message: '上传成功' message: '上传成功'
}) })
if (res.code === 0) { if (res.code === 0) {
this.getTableData()
getTableData()
} }
} else { } else {
this.$message({
ElMessage({
type: 'warning', type: 'warning',
message: res.msg message: res.msg
}) })
} }
},
uploadError() {
this.$message({
}
const uploadError = () => {
ElMessage({
type: 'error', type: 'error',
message: '上传失败' message: '上传失败'
}) })
this.fullscreenLoading = false
},
downloadFile(row) {
fullscreenLoading.value = false
}
const downloadFile = (row) => {
if (row.url.indexOf('http://') > -1 || row.url.indexOf('https://') > -1) { if (row.url.indexOf('http://') > -1 || row.url.indexOf('https://') > -1) {
downloadImage(row.url, row.name) downloadImage(row.url, row.name)
} else { } else {
downloadImage(this.path + row.url, row.name)
}
}
downloadImage(path.value + row.url, row.name)
} }
} }
</script>
<script>
export default {
name: 'Upload'
}
</script> </script>
<style scoped> <style scoped>
.upload-btn+.upload-btn { .upload-btn+.upload-btn {

5
web/src/view/superAdmin/menu/menu.vue

@ -412,13 +412,8 @@ const editMenu = async(id) => {
</script> </script>
<script> <script>
// mixins getTableData
export default { export default {
name: 'Menus', name: 'Menus',
methods: {
}
} }
</script> </script>

4
web/src/view/superAdmin/operation/sysOperationRecord.vue

@ -209,9 +209,9 @@ const deleteSysOperationRecordFunc = async(row) => {
message: '删除成功' message: '删除成功'
}) })
if (tableData.value.length === 1 && page.value > 1) { if (tableData.value.length === 1 && page.value > 1) {
this.page--
page.value--
} }
this.getTableData()
getTableData()
} }
} }
const fmtBody = (value) => { const fmtBody = (value) => {

52
web/src/view/system/state.vue

@ -138,37 +138,37 @@
</div> </div>
</template> </template>
<script>
<script setup>
import { getSystemState } from '@/api/system' import { getSystemState } from '@/api/system'
export default {
name: 'State',
data() {
return {
timer: null,
state: {},
colors: [
import { onUnmounted, ref } from 'vue'
const timer = ref(null)
const state = ref({})
const colors = ref([
{ color: '#5cb87a', percentage: 20 }, { color: '#5cb87a', percentage: 20 },
{ color: '#e6a23c', percentage: 40 }, { color: '#e6a23c', percentage: 40 },
{ color: '#f56c6c', percentage: 80 } { color: '#f56c6c', percentage: 80 }
]
}
},
created() {
this.reload()
this.timer = setInterval(() => {
this.reload()
}, 1000 * 10)
},
beforeUnmount() {
clearInterval(this.timer)
this.timer = null
},
methods: {
async reload() {
])
const reload = async() => {
const { data } = await getSystemState() const { data } = await getSystemState()
this.state = data.server
}
}
state.value = data.server
}
reload()
timer.value = setInterval(() => {
reload()
}, 1000 * 10)
onUnmounted(() => {
clearInterval(timer.value)
timer.value = null
})
</script>
<script>
export default {
name: 'State',
} }
</script> </script>

7
web/src/view/systemTools/autoCode/component/previewCodeDialg.vue

@ -25,6 +25,7 @@ const props = defineProps({
} }
}) })
const activeName = ref('')
onMounted(() => { onMounted(() => {
marked.setOptions({ marked.setOptions({
renderer: new marked.Renderer(), renderer: new marked.Renderer(),
@ -41,15 +42,13 @@ onMounted(() => {
xhtml: false xhtml: false
}) })
for (const key in props.previewCode) { for (const key in props.previewCode) {
if (this.activeName === '') {
this.activeName = key
if (activeName.value === '') {
activeName.value = key
} }
document.getElementById(key).innerHTML = marked(props.previewCode[key]) document.getElementById(key).innerHTML = marked(props.previewCode[key])
} }
}) })
const activeName = ref('')
const selectText = () => { const selectText = () => {
const element = document.getElementById(activeName.value) const element = document.getElementById(activeName.value)
if (document.body.createTextRange) { if (document.body.createTextRange) {

2
web/src/view/systemTools/system/system.vue

@ -2,7 +2,7 @@
<div class="system"> <div class="system">
<el-form ref="form" :model="config" label-width="240px"> <el-form ref="form" :model="config" label-width="240px">
<!-- System start --> <!-- System start -->
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse v-model="activeNames">
<el-collapse-item title="系统配置" name="1"> <el-collapse-item title="系统配置" name="1">
<el-form-item label="环境值"> <el-form-item label="环境值">
<el-input v-model="config.system.env" /> <el-input v-model="config.system.env" />

Loading…
Cancel
Save