添加前端
This commit is contained in:
64
Yi.Vue2.x/src/components/Links.vue
Normal file
64
Yi.Vue2.x/src/components/Links.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<v-container>
|
||||
<v-row align="center">
|
||||
<v-col
|
||||
v-for="(link, i) in links"
|
||||
:key="i"
|
||||
class="text-center"
|
||||
cols="6"
|
||||
md="auto"
|
||||
>
|
||||
<a
|
||||
:href="link.href"
|
||||
class="text-decoration-none text-uppercase text-caption font-weight-regular"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
v-text="link.text"
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
<v-spacer class="hidden-sm-and-down" />
|
||||
|
||||
<v-col
|
||||
cols="12"
|
||||
md="auto"
|
||||
>
|
||||
<div class="text-body-1 font-weight-light pt-6 pt-md-0 text-center">
|
||||
© {{ (new Date()).getFullYear() }}, Made by <v-icon>mdi-vuetify</v-icon>
|
||||
<a
|
||||
href="https://ccnetcore"
|
||||
class="text-decoration-none"
|
||||
>ccnetcore</a>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Links',
|
||||
|
||||
data: () => ({
|
||||
links: [
|
||||
{
|
||||
href: '#',
|
||||
text: 'YiFramework文档',
|
||||
},
|
||||
{
|
||||
href: '#',
|
||||
text: 'GitHub',
|
||||
},
|
||||
{
|
||||
href: '#',
|
||||
text: '论坛',
|
||||
}
|
||||
],
|
||||
}),
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
a
|
||||
color: inherit !important
|
||||
</style>
|
||||
59
Yi.Vue2.x/src/components/MaterialAlert.vue
Normal file
59
Yi.Vue2.x/src/components/MaterialAlert.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<v-alert
|
||||
class="v-alert--material"
|
||||
dark
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<template
|
||||
v-if="$attrs.icon"
|
||||
v-slot:prepend
|
||||
>
|
||||
<v-avatar
|
||||
class="align-self-start mt-n9 elevation-6 mr-4"
|
||||
size="38"
|
||||
>
|
||||
<v-icon
|
||||
:color="$attrs.color"
|
||||
class="elevation-6 white"
|
||||
light
|
||||
>
|
||||
{{ $attrs.icon }}
|
||||
</v-icon>
|
||||
</v-avatar>
|
||||
</template>
|
||||
|
||||
<slot />
|
||||
|
||||
<template
|
||||
v-if="$attrs.dismissible"
|
||||
v-slot:close="{ toggle }"
|
||||
>
|
||||
<v-btn
|
||||
:aria-label="$vuetify.lang.t('$vuetify.close')"
|
||||
class="ml-4"
|
||||
color
|
||||
icon
|
||||
small
|
||||
@click="toggle"
|
||||
>
|
||||
<v-icon>
|
||||
$vuetify.icons.cancel
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-alert>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default { name: 'MaterialAlert' }
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.v-alert--material
|
||||
margin-top: 32px
|
||||
|
||||
.v-alert__dismissible
|
||||
align-self: flex-start
|
||||
margin: 0 0 0 16px !important
|
||||
</style>
|
||||
113
Yi.Vue2.x/src/components/MaterialCard.vue
Normal file
113
Yi.Vue2.x/src/components/MaterialCard.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<app-card
|
||||
v-bind="$attrs"
|
||||
class="v-card--material mt-4"
|
||||
>
|
||||
<v-card-title class="align-start">
|
||||
<v-sheet
|
||||
:color="color"
|
||||
:width="fullHeader ? '100%' : undefined"
|
||||
class="overflow-hidden mt-n9 transition-swing v-card--material__sheet"
|
||||
elevation="6"
|
||||
max-width="100%"
|
||||
rounded
|
||||
>
|
||||
<v-theme-provider
|
||||
v-if="hasHeading"
|
||||
dark
|
||||
>
|
||||
<div
|
||||
v-if="icon"
|
||||
:class="iconSmall ? 'pa-7' : 'pa-8'"
|
||||
>
|
||||
<v-icon
|
||||
:large="!iconSmall"
|
||||
v-text="icon"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<slot name="heading" />
|
||||
|
||||
<div
|
||||
v-if="heading"
|
||||
class="text-h4 white--text pa-7 v-card--material__title"
|
||||
>
|
||||
{{ heading }}
|
||||
</div>
|
||||
</v-theme-provider>
|
||||
</v-sheet>
|
||||
|
||||
<div
|
||||
v-if="hasTitle"
|
||||
:class="fullHeader ? 'pt-4' : 'pl-3'"
|
||||
class="text-h4 v-card--material__title"
|
||||
>
|
||||
<slot name="title" />
|
||||
|
||||
<template v-if="title">
|
||||
{{ title }}
|
||||
</template>
|
||||
|
||||
<div class="text-subtitle-1 mb-n4">
|
||||
<slot name="subtitle" />
|
||||
|
||||
<template v-if="subtitle">
|
||||
{{ subtitle }}
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</v-card-title>
|
||||
|
||||
<slot />
|
||||
|
||||
<template v-if="$slots.actions">
|
||||
<v-divider class="mt-2 mx-4" />
|
||||
|
||||
<v-card-actions class="px-4 text-caption grey--text">
|
||||
<slot name="actions" />
|
||||
</v-card-actions>
|
||||
</template>
|
||||
</app-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MaterialCard',
|
||||
|
||||
props: {
|
||||
color: String,
|
||||
fullHeader: Boolean,
|
||||
heading: String,
|
||||
icon: String,
|
||||
iconSmall: Boolean,
|
||||
subtitle: String,
|
||||
title: String,
|
||||
},
|
||||
|
||||
computed: {
|
||||
hasHeading () {
|
||||
return !!(
|
||||
this.icon ||
|
||||
this.heading ||
|
||||
this.$slots.heading
|
||||
)
|
||||
},
|
||||
hasTitle () {
|
||||
return !!(
|
||||
this.title ||
|
||||
this.subtitle ||
|
||||
this.$slots.title ||
|
||||
this.$slots.subtitle
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.v-card.v-card--material
|
||||
> .v-card__title
|
||||
> .v-card--material__title
|
||||
flex: 1 1 auto
|
||||
word-break: break-word
|
||||
</style>
|
||||
93
Yi.Vue2.x/src/components/MaterialChartCard.vue
Normal file
93
Yi.Vue2.x/src/components/MaterialChartCard.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<material-card
|
||||
v-bind="$attrs"
|
||||
class="v-card--material-chart"
|
||||
full-header
|
||||
>
|
||||
<template #heading>
|
||||
<div class="pa-4">
|
||||
<chartist
|
||||
:data="data"
|
||||
:event-handlers="eventHandlers"
|
||||
:options="options"
|
||||
:ratio="ratio"
|
||||
:responsive-options="responsiveOptions"
|
||||
:type="type"
|
||||
style="max-height: 150px;"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #subtitle>
|
||||
<slot name="subtitle" />
|
||||
</template>
|
||||
|
||||
<slot />
|
||||
|
||||
<template #actions>
|
||||
<slot name="actions" />
|
||||
</template>
|
||||
</material-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MaterialChartCard',
|
||||
|
||||
inheritAttrs: false,
|
||||
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
eventHandlers: {
|
||||
type: Array,
|
||||
default: () => ([]),
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
ratio: String,
|
||||
responsiveOptions: {
|
||||
type: Array,
|
||||
default: () => ([]),
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator: v => ['Bar', 'Line', 'Pie'].includes(v),
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.v-card--material-chart
|
||||
p
|
||||
color: #999
|
||||
|
||||
.v-card--material__sheet
|
||||
max-height: 185px
|
||||
width: 100%
|
||||
|
||||
.ct-label
|
||||
color: rgba(255, 255, 255, 1)
|
||||
opacity: .7
|
||||
font-size: 0.875rem
|
||||
font-weight: 300
|
||||
|
||||
.ct-grid
|
||||
stroke: hsla(0,0%,100%,.2)
|
||||
|
||||
.ct-series-a .ct-point,
|
||||
.ct-series-a .ct-line,
|
||||
.ct-series-a .ct-bar,
|
||||
.ct-series-a .ct-slice-donut
|
||||
stroke: rgba(255,255,255,.8)
|
||||
|
||||
.ct-series-a .ct-slice-pie,
|
||||
.ct-series-a .ct-area
|
||||
fill: rgba(255,255,255,.4)
|
||||
</style>
|
||||
78
Yi.Vue2.x/src/components/MaterialSnackbar.vue
Normal file
78
Yi.Vue2.x/src/components/MaterialSnackbar.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<v-snackbar
|
||||
v-model="internalValue"
|
||||
class="v-snackbar--material"
|
||||
v-bind="{
|
||||
...$attrs,
|
||||
'color': 'transparent'
|
||||
}"
|
||||
>
|
||||
<material-alert
|
||||
v-model="internalValue"
|
||||
:color="$attrs.color"
|
||||
:dismissible="dismissible"
|
||||
:type="type"
|
||||
class="ma-0"
|
||||
dark
|
||||
>
|
||||
<slot />
|
||||
</material-alert>
|
||||
</v-snackbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MaterialSnackbar',
|
||||
|
||||
props: {
|
||||
dismissible: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
value: Boolean,
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
internalValue: this.value,
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
internalValue (val, oldVal) {
|
||||
if (val === oldVal) return
|
||||
|
||||
this.$emit('input', val)
|
||||
},
|
||||
value (val, oldVal) {
|
||||
if (val === oldVal) return
|
||||
|
||||
this.internalValue = val
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.v-snackbar--material
|
||||
margin-top: 32px
|
||||
margin-bottom: 32px
|
||||
|
||||
.v-alert
|
||||
padding: 32px 16px
|
||||
|
||||
.v-alert--material,
|
||||
.v-snack__wrapper
|
||||
border-radius: 4px
|
||||
|
||||
.v-snack__content
|
||||
overflow: visible
|
||||
padding: 0
|
||||
|
||||
.v-snack__action
|
||||
display: none
|
||||
</style>
|
||||
39
Yi.Vue2.x/src/components/MaterialStatsCard.vue
Normal file
39
Yi.Vue2.x/src/components/MaterialStatsCard.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<material-card
|
||||
class="v-card--material-stats"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<template #subtitle>
|
||||
<div
|
||||
class="text-right text-h3 v-card__subtitle--material-stats"
|
||||
v-text="value"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<slot name="actions" />
|
||||
</template>
|
||||
|
||||
<slot />
|
||||
</material-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MaterialStatCard',
|
||||
|
||||
props: { value: String },
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.v-card--material-stats.v-card--material .v-card--material__title
|
||||
color: #999999
|
||||
font-size: .875rem !important
|
||||
margin-left: auto
|
||||
text-align: right
|
||||
|
||||
.v-card__subtitle--material-stats
|
||||
color: #3C4858
|
||||
</style>
|
||||
30
Yi.Vue2.x/src/components/TableApi.js
Normal file
30
Yi.Vue2.x/src/components/TableApi.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import myaxios from '@/util/myaxios'
|
||||
export default {
|
||||
getItem(url) {
|
||||
return myaxios({
|
||||
url: url,
|
||||
method: 'get'
|
||||
})
|
||||
},
|
||||
addItem(url, data) {
|
||||
return myaxios({
|
||||
url: url,
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
updateItem(url, data) {
|
||||
return myaxios({
|
||||
url: url,
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
},
|
||||
delItemList(url, Ids) {
|
||||
return myaxios({
|
||||
url: url,
|
||||
method: 'delete',
|
||||
data: Ids
|
||||
})
|
||||
},
|
||||
}
|
||||
37
Yi.Vue2.x/src/components/ViewIntro.vue
Normal file
37
Yi.Vue2.x/src/components/ViewIntro.vue
Normal file
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<section class="mb-12 text-center">
|
||||
<h1
|
||||
class="mb-2 text-h3"
|
||||
v-text="heading"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-if="link"
|
||||
class="text-body-2 font-weight-light"
|
||||
>
|
||||
Please checkout the <a
|
||||
:href="`https://vuetifyjs.com/en/${link}`"
|
||||
class="text-decoration-none secondary--text"
|
||||
target="_blank"
|
||||
>full documentation</a>
|
||||
</div>
|
||||
|
||||
<v-responsive
|
||||
class="text-center mx-auto text-body-1 font-weight-light"
|
||||
max-width="400"
|
||||
>
|
||||
<slot />
|
||||
</v-responsive>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ViewIntro',
|
||||
|
||||
props: {
|
||||
heading: String,
|
||||
link: String,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
29
Yi.Vue2.x/src/components/app/BarItem.vue
Normal file
29
Yi.Vue2.x/src/components/app/BarItem.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<script>
|
||||
import { VHover, VListItem } from 'vuetify/lib'
|
||||
|
||||
export default {
|
||||
name: 'AppBarItem',
|
||||
|
||||
render (h) {
|
||||
return h(VHover, {
|
||||
scopedSlots: {
|
||||
default: ({ hover }) => {
|
||||
return h(VListItem, {
|
||||
attrs: this.$attrs,
|
||||
class: {
|
||||
'black--text': !hover,
|
||||
'white--text secondary elevation-12': hover,
|
||||
},
|
||||
props: {
|
||||
activeClass: '',
|
||||
dark: hover,
|
||||
link: true,
|
||||
...this.$attrs,
|
||||
},
|
||||
}, this.$slots.default)
|
||||
},
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
22
Yi.Vue2.x/src/components/app/Btn.vue
Normal file
22
Yi.Vue2.x/src/components/app/Btn.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<v-btn
|
||||
:color="color"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<slot />
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppBtn',
|
||||
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
12
Yi.Vue2.x/src/components/app/Card.vue
Normal file
12
Yi.Vue2.x/src/components/app/Card.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<v-card
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<slot />
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default { name: 'AppCard' }
|
||||
</script>
|
||||
42
Yi.Vue2.x/src/components/app/Tabs.vue
Normal file
42
Yi.Vue2.x/src/components/app/Tabs.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<v-tabs
|
||||
:active-class="`${color} ${theme.isDark ? 'black' : 'white'}--text`"
|
||||
class="v-tabs--pill"
|
||||
hide-slider
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
>
|
||||
<slot />
|
||||
|
||||
<slot name="items" />
|
||||
</v-tabs>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppTabs',
|
||||
|
||||
inject: ['theme'],
|
||||
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass">
|
||||
.v-tabs--pill
|
||||
.v-tab,
|
||||
.v-tab:before
|
||||
border-radius: 24px
|
||||
|
||||
&.v-tabs--icons-and-text
|
||||
&:not(.v-tabs--vertical) > .v-tabs-bar
|
||||
height: 100px
|
||||
.v-tab,
|
||||
.v-tab:before
|
||||
border-radius: 4px
|
||||
</style>
|
||||
28
Yi.Vue2.x/src/components/ccAvatar.vue
Normal file
28
Yi.Vue2.x/src/components/ccAvatar.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<v-avatar :size="size" >
|
||||
<!-- <img src="https://z3.ax1x.com/2021/05/09/gJadhD.jpg" /> -->
|
||||
<img
|
||||
:src="baseurl +'/image/'+$store.state.user.user.icon"
|
||||
/>
|
||||
</v-avatar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// Utilities
|
||||
// import { get } from 'vuex-pathify'
|
||||
|
||||
export default {
|
||||
name: 'ccAvatar',
|
||||
mounted() {
|
||||
this.baseurl = process.env.VUE_APP_BASE_API;
|
||||
},
|
||||
data:()=>({
|
||||
baseurl: "",
|
||||
}),
|
||||
props: {
|
||||
size: {
|
||||
type: Number,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
67
Yi.Vue2.x/src/components/ccCombobox.vue
Normal file
67
Yi.Vue2.x/src/components/ccCombobox.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<v-dialog v-model="dialog" persistent max-width="600px">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn class="ma-2" color="primary" dark v-bind="attrs" v-on="on">
|
||||
{{ headers }}
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span class="text-h5">{{ headers }}</span>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-combobox
|
||||
v-model="select"
|
||||
:items="items"
|
||||
label="请点击选择"
|
||||
multiple
|
||||
chips
|
||||
:item-text="itemText"
|
||||
></v-combobox>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<small>*可多选</small>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="blue darken-1" text @click="dialog = false"> 关闭 </v-btn>
|
||||
<div @click="dialog = false"> <slot name="save" ></slot> </div>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
headers: {
|
||||
type: String
|
||||
},
|
||||
items:{
|
||||
type:Array
|
||||
},
|
||||
itemText:{
|
||||
type: String
|
||||
}
|
||||
},
|
||||
name: "ccCombobox",
|
||||
data() {
|
||||
return {
|
||||
dialog: false,
|
||||
select: [],
|
||||
};
|
||||
},
|
||||
watch:{
|
||||
select:{//深度监听,可监听到对象、数组的变化
|
||||
handler(val, oldVal){
|
||||
this.$emit("select",val);
|
||||
},
|
||||
deep:true
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
245
Yi.Vue2.x/src/components/ccTable.vue
Normal file
245
Yi.Vue2.x/src/components/ccTable.vue
Normal file
@@ -0,0 +1,245 @@
|
||||
<template>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="desserts"
|
||||
sort-by="calories"
|
||||
class="elevation-1"
|
||||
item-key="id"
|
||||
show-select
|
||||
v-model="selected"
|
||||
:search="search"
|
||||
>
|
||||
<slot />
|
||||
<template v-slot:top>
|
||||
<!-- 搜索框 -->
|
||||
<v-toolbar flat>
|
||||
<v-spacer></v-spacer>
|
||||
<v-text-field
|
||||
v-model="search"
|
||||
append-icon="mdi-magnify"
|
||||
label="搜索"
|
||||
single-line
|
||||
hide-details
|
||||
class="mx-4"
|
||||
></v-text-field>
|
||||
|
||||
<v-btn
|
||||
v-if="axiosUrls.add != null"
|
||||
color="primary"
|
||||
dark
|
||||
class="mb-2 mx-2"
|
||||
@click="dialog = true"
|
||||
>
|
||||
添加新项
|
||||
</v-btn>
|
||||
|
||||
<!-- 添加提示框 -->
|
||||
<v-dialog
|
||||
v-if="axiosUrls.add != null"
|
||||
v-model="dialog"
|
||||
max-width="500px"
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span class="headline">{{ formTitle }}</span>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col
|
||||
cols="12"
|
||||
sm="6"
|
||||
md="4"
|
||||
v-for="(value, key, index) in editedItem"
|
||||
:key="index"
|
||||
>
|
||||
<v-text-field
|
||||
v-model="editedItem[key]"
|
||||
:label="key"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="blue darken-1" text @click="close"> 取消 </v-btn>
|
||||
<v-btn color="blue darken-1" text @click="save"> 保存 </v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-btn
|
||||
v-if="axiosUrls.del != null"
|
||||
color="secondary"
|
||||
class="mb-2"
|
||||
@click="deleteItem(null)"
|
||||
>
|
||||
删除所选
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
</template>
|
||||
|
||||
<!-- 表格中的删除和修改 -->
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<slot name="action" :item="item"></slot>
|
||||
|
||||
<v-icon
|
||||
v-if="axiosUrls.update != null"
|
||||
small
|
||||
class="mr-2"
|
||||
@click="editItem(item)"
|
||||
>
|
||||
mdi-pencil
|
||||
</v-icon>
|
||||
<v-icon v-if="axiosUrls.del != null" small @click="deleteItem(item)">
|
||||
mdi-delete
|
||||
</v-icon>
|
||||
</template>
|
||||
|
||||
<!-- 初始化 -->
|
||||
<template v-slot:no-data>
|
||||
<v-btn color="primary" @click="initialize"> 刷新 </v-btn>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</template>
|
||||
<script>
|
||||
import itemApi from "./TableApi.js";
|
||||
export default {
|
||||
name: "ccTable",
|
||||
props: {
|
||||
defaultItem: {
|
||||
type: Object,
|
||||
},
|
||||
headers: {
|
||||
type: Array,
|
||||
},
|
||||
axiosUrls: {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
page: 1,
|
||||
selected: [],
|
||||
search: "",
|
||||
dialog: false,
|
||||
desserts: [],
|
||||
editedIndex: -1,
|
||||
editedItem: {},
|
||||
}),
|
||||
|
||||
computed: {
|
||||
formTitle() {
|
||||
return this.editedIndex === -1 ? "添加数据" : "编辑数据";
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
axiosUrls: {
|
||||
handler(val, oldVal) {
|
||||
this.dataInit(val.get);
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
selected: {
|
||||
handler(val, oldVal) {
|
||||
this.$emit("selected", val);
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
dialog(val) {
|
||||
val || this.close();
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.initialize();
|
||||
},
|
||||
|
||||
methods: {
|
||||
dataInit(getStr) {
|
||||
itemApi.getItem(getStr).then((resp) => {
|
||||
const response = resp.data;
|
||||
this.desserts = response;
|
||||
});
|
||||
},
|
||||
initialize() {
|
||||
if(this.axiosUrls.get!=undefined && this.axiosUrls.get!=null )
|
||||
{
|
||||
this.dataInit(this.axiosUrls.get)
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.editedItem = Object.assign({}, this.defaultItem);
|
||||
this.editedIndex = -1;
|
||||
});
|
||||
},
|
||||
// 添加和修改都打开同一个编辑框
|
||||
|
||||
editItem(item) {
|
||||
this.editedIndex = this.desserts.indexOf(item);
|
||||
this.editedItem = Object.assign({}, item);
|
||||
this.dialog = true;
|
||||
},
|
||||
|
||||
async deleteItem(item) {
|
||||
this.editedIndex = this.desserts.indexOf(item);
|
||||
this.editedItem = Object.assign({}, item);
|
||||
|
||||
var p = await this.$dialog.warning({
|
||||
text: "你确定要删除此条记录吗??",
|
||||
title: "警告",
|
||||
actions: {
|
||||
false: "取消",
|
||||
true: "确定",
|
||||
},
|
||||
});
|
||||
if (p) {
|
||||
this.deleteItemConfirm();
|
||||
}
|
||||
},
|
||||
deleteItemConfirm() {
|
||||
var Ids = [];
|
||||
if (this.editedIndex > -1) {
|
||||
Ids.push(this.editedItem.id);
|
||||
} else {
|
||||
this.selected.forEach(function (item) {
|
||||
Ids.push(item.id);
|
||||
});
|
||||
}
|
||||
itemApi
|
||||
.delItemList(this.axiosUrls.del, Ids)
|
||||
.then(() => this.initialize());
|
||||
},
|
||||
close() {
|
||||
this.dialog = false;
|
||||
this.$nextTick(() => {
|
||||
this.editedItem = Object.assign({}, this.defaultItem);
|
||||
this.editedIndex = -1;
|
||||
});
|
||||
},
|
||||
|
||||
closeDelete() {
|
||||
this.dialogDelete = false;
|
||||
this.$nextTick(() => {
|
||||
this.editedItem = Object.assign({}, this.defaultItem);
|
||||
this.editedIndex = -1;
|
||||
});
|
||||
},
|
||||
|
||||
save() {
|
||||
if (this.editedIndex > -1) {
|
||||
itemApi
|
||||
.updateItem(this.axiosUrls.update, this.editedItem)
|
||||
.then(() => this.initialize());
|
||||
} else {
|
||||
itemApi
|
||||
.addItem(this.axiosUrls.add, this.editedItem)
|
||||
.then(() => this.initialize());
|
||||
}
|
||||
this.close();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
227
Yi.Vue2.x/src/components/ccTreeview.vue
Normal file
227
Yi.Vue2.x/src/components/ccTreeview.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-divider></v-divider>
|
||||
<app-btn dark class="ma-4" @click="showAll"> 展开全部</app-btn>
|
||||
<app-btn dark class="my-4 mr-4" @click="dialog = true"> 添加新项 </app-btn>
|
||||
<app-btn dark class="my-4" color="secondary" @click="deleteItem(null)">
|
||||
删除所选
|
||||
</app-btn>
|
||||
|
||||
|
||||
|
||||
|
||||
<v-dialog v-model="dialog" max-width="500px">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span class="headline">{{ formTitle }}</span>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col
|
||||
cols="12"
|
||||
sm="6"
|
||||
md="4"
|
||||
v-for="(value, key, index) in editedItem"
|
||||
:key="index"
|
||||
>
|
||||
<v-text-field
|
||||
v-model="editedItem[key]"
|
||||
:label="key"
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="blue darken-1" text @click="close"> 取消 </v-btn>
|
||||
<v-btn color="blue darken-1" text @click="save"> 保存 </v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<v-treeview
|
||||
ref="tree"
|
||||
open-on-click
|
||||
selectable
|
||||
:items="desserts"
|
||||
:selection-type="selectionType"
|
||||
v-model="selection"
|
||||
return-object
|
||||
open-all
|
||||
hoverable
|
||||
item-text="menu_name"
|
||||
>
|
||||
<template v-slot:append="{ item }">
|
||||
<v-btn class="mr-2">编号:{{ item.id }}</v-btn>
|
||||
<v-btn class="mr-2">图标:{{ item.icon }}</v-btn>
|
||||
<v-btn class="mr-2">路由:{{ item.router }}</v-btn>
|
||||
<v-btn v-if="item.mould" class="mr-2">接口名:{{ item.mould.mould_name }}</v-btn>
|
||||
<v-btn v-if="item.mould" class="mr-2" color="secondary">接口地址:{{ item.mould.url }}</v-btn>
|
||||
<ccCombobox
|
||||
headers="设置接口权限"
|
||||
itemText="url"
|
||||
:items="mouldList"
|
||||
@select="getSelect"
|
||||
>
|
||||
<template v-slot:save>
|
||||
<v-btn @click="setMould(item)" color="blue darken-1" text>
|
||||
保存</v-btn
|
||||
>
|
||||
</template>
|
||||
</ccCombobox>
|
||||
<app-btn
|
||||
@click="
|
||||
parentId = item.id;
|
||||
dialog = true;
|
||||
"
|
||||
>添加子菜单</app-btn
|
||||
>
|
||||
<app-btn class="mx-2" @click="editItem(item)">编辑</app-btn>
|
||||
|
||||
<app-btn color="secondary" class="mr-2" @click="deleteItem(item)">删除</app-btn>
|
||||
|
||||
</template>
|
||||
</v-treeview>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import mouldApi from "../api/mouldApi";
|
||||
import menuApi from "../api/menuApi";
|
||||
export default {
|
||||
name: "ccTreeview",
|
||||
|
||||
data: () => ({
|
||||
mouldSelect: [],
|
||||
mouldList: [],
|
||||
desserts: [],
|
||||
selectionType: "independent",
|
||||
selection: [],
|
||||
dialog: false,
|
||||
editedItem: {},
|
||||
editedIndex: -1,
|
||||
parentId: 0,
|
||||
defaultItem: {
|
||||
icon: "mdi-start",
|
||||
router: "test",
|
||||
menu_name: "测试",
|
||||
is_show:1
|
||||
},
|
||||
}),
|
||||
computed: {
|
||||
formTitle() {
|
||||
return this.editedIndex === -1 ? "添加数据" : "编辑数据";
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
},
|
||||
methods: {
|
||||
showAll(){
|
||||
this.$refs.tree.updateAll(true);
|
||||
},
|
||||
|
||||
setMould(item) {
|
||||
menuApi.SetMouldByMenu(item.id, this.mouldSelect[0].id).then((resp) => {
|
||||
this.$dialog.notify.info(resp.msg, {
|
||||
position: "top-right",
|
||||
timeout: 5000,
|
||||
});
|
||||
this.init();
|
||||
});
|
||||
},
|
||||
|
||||
getSelect(data) {
|
||||
this.mouldSelect = data;
|
||||
},
|
||||
async deleteItem(item) {
|
||||
this.editedIndex = this.desserts.indexOf(item);
|
||||
this.editedItem = Object.assign({}, item);
|
||||
var p = await this.$dialog.warning({
|
||||
text: "你确定要删除此条记录吗??",
|
||||
title: "警告",
|
||||
actions: {
|
||||
false: "取消",
|
||||
true: "确定",
|
||||
},
|
||||
});
|
||||
if (p) {
|
||||
this.deleteItemConfirm();
|
||||
}
|
||||
},
|
||||
deleteItemConfirm() {
|
||||
var Ids = [];
|
||||
if (this.editedIndex > -1) {
|
||||
Ids.push(this.editedItem.id);
|
||||
} else {
|
||||
this.selection.forEach(function (item) {
|
||||
Ids.push(item.id);
|
||||
});
|
||||
}
|
||||
menuApi.DelListMenu(Ids).then(() => this.init());
|
||||
},
|
||||
|
||||
close() {
|
||||
this.dialog = false;
|
||||
this.$nextTick(() => {
|
||||
this.editedItem = Object.assign({}, this.defaultItem);
|
||||
this.editedIndex = -1;
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.parentId = 0;
|
||||
mouldApi.getMould().then((resp) => {
|
||||
this.mouldList = resp.data;
|
||||
});
|
||||
|
||||
menuApi.GetMenuInMould().then((resp) => {
|
||||
this.desserts =[ resp.data];
|
||||
});
|
||||
this.$nextTick(() => {
|
||||
this.editedItem = Object.assign({}, this.defaultItem);
|
||||
this.editedIndex = -1;
|
||||
});
|
||||
|
||||
|
||||
|
||||
},
|
||||
editItem(item) {
|
||||
this.editedIndex = item.id;
|
||||
this.editedItem = Object.assign({}, item);
|
||||
this.dialog = true;
|
||||
},
|
||||
|
||||
save() {
|
||||
if (this.editedIndex > -1) {
|
||||
menuApi.UpdateMenu(this.editedItem).then(() => this.init());
|
||||
} else {
|
||||
if (this.parentId == 0) {
|
||||
menuApi.AddTopMenu(this.editedItem).then(() => {
|
||||
this.init();
|
||||
});
|
||||
} else {
|
||||
menuApi.addChildrenMenu(this.parentId, this.editedItem).then(() => {
|
||||
this.init();
|
||||
});
|
||||
}
|
||||
}
|
||||
this.close();
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
selection: {
|
||||
//深度监听,可监听到对象、数组的变化
|
||||
handler(val, oldVal) {
|
||||
this.$emit("selection", val);
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
dialog(val) {
|
||||
val || this.close();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user