refactor: eslint代码检查优化
Former-commit-id: 4c11b5d0cdd10f28148cf3d9b593f85e082cdc51
This commit is contained in:
@@ -18,7 +18,7 @@ export function listCategories(queryParams:object){
|
|||||||
*
|
*
|
||||||
* @param queryParams
|
* @param queryParams
|
||||||
*/
|
*/
|
||||||
export function listCascadeCategories(queryParams:object) {
|
export function listCascadeCategories(queryParams?:object) {
|
||||||
return request({
|
return request({
|
||||||
url: '/mall-pms/api/v1/categories/cascade',
|
url: '/mall-pms/api/v1/categories/cascade',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GoodsPageResult, GoodsQueryParam } from '@/types'
|
import { GoodsDetail, GoodsPageResult, GoodsQueryParam } from '@/types'
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import { AxiosPromise } from 'axios'
|
import { AxiosPromise } from 'axios'
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ export function listGoodsPages(queryParams: GoodsQueryParam):AxiosPromise<GoodsP
|
|||||||
*
|
*
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
export function getGoodsFormDetail(id: number) {
|
export function getGoodsDetail(id: string):AxiosPromise<GoodsDetail> {
|
||||||
return request({
|
return request({
|
||||||
url: '/mall-pms/api/v1/goods/' + id,
|
url: '/mall-pms/api/v1/goods/' + id,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import request from '@/utils/request'
|
|||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
export function uploadFile(file: File) {
|
export function uploadFile(file: File) {
|
||||||
let formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
return request(
|
return request(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export function listRoleMenuIds(roleId: number):AxiosPromise<number[]> {
|
|||||||
* @param roleId
|
* @param roleId
|
||||||
* @param menuIds
|
* @param menuIds
|
||||||
*/
|
*/
|
||||||
export function updateRoleMenu(roleId: number, menuIds: Array<Number>) {
|
export function updateRoleMenu(roleId: number, menuIds: Array<number>) {
|
||||||
return request({
|
return request({
|
||||||
url: '/youlai-admin/api/v1/roles/' + roleId + '/menus',
|
url: '/youlai-admin/api/v1/roles/' + roleId + '/menus',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import request from "@/utils/request";
|
import request from "@/utils/request";
|
||||||
import { AxiosPromise } from "axios";
|
import { AxiosPromise } from "axios";
|
||||||
import { UserFormData, UserImportFormData, UserInfo, UserPageResult, UserQueryParam } from "@/types";
|
import { UserFormData, UserInfo, UserPageResult, UserQueryParam } from "@/types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录成功后获取用户信息(昵称、头像、权限集合和角色集合)
|
* 登录成功后获取用户信息(昵称、头像、权限集合和角色集合)
|
||||||
@@ -113,6 +113,7 @@ export function exportUser(queryParams: UserQueryParam) {
|
|||||||
return request({
|
return request({
|
||||||
url: '/youlai-admin/api/v1/users/_export',
|
url: '/youlai-admin/api/v1/users/_export',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
params:queryParams,
|
||||||
responseType: "arraybuffer"
|
responseType: "arraybuffer"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -123,7 +124,7 @@ export function exportUser(queryParams: UserQueryParam) {
|
|||||||
* @param file
|
* @param file
|
||||||
*/
|
*/
|
||||||
export function importUser(deptId: number, roleIds: string, file: File) {
|
export function importUser(deptId: number, roleIds: string, file: File) {
|
||||||
let formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
formData.append('deptId',deptId.toString())
|
formData.append('deptId',deptId.toString())
|
||||||
formData.append('roleIds',roleIds)
|
formData.append('roleIds',roleIds)
|
||||||
|
|||||||
9
src/components.d.ts
vendored
Normal file
9
src/components.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// 全局组件类型声明
|
||||||
|
import Pagination from "@/components/Pagination/index.vue";
|
||||||
|
|
||||||
|
declare module "@vue/runtime-core" {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
Pagination: typeof Pagination;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export {}
|
||||||
@@ -1,13 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="icon-body">
|
<div class="icon-body">
|
||||||
<el-input
|
<el-input v-model="iconName" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons"
|
||||||
v-model="iconName"
|
@input="filterIcons">
|
||||||
style="position: relative;"
|
|
||||||
clearable
|
|
||||||
placeholder="请输入图标名称"
|
|
||||||
@clear="filterIcons"
|
|
||||||
@input="filterIcons"
|
|
||||||
>
|
|
||||||
<template #suffix><i class="el-icon-search el-input__icon" /></template>
|
<template #suffix><i class="el-icon-search el-input__icon" /></template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<div class="icon-list">
|
<div class="icon-list">
|
||||||
@@ -19,11 +13,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { ref} from "vue";
|
import { ref } from "vue";
|
||||||
import SvgIcon from '@/components/SvgIcon/index.vue';
|
import SvgIcon from '@/components/SvgIcon/index.vue';
|
||||||
|
|
||||||
let icons = []
|
const icons = [] as string[]
|
||||||
const modules = import.meta.glob('../../assets/icons/svg/*.svg');
|
const modules = import.meta.glob('../../assets/icons/svg/*.svg');
|
||||||
for (const path in modules) {
|
for (const path in modules) {
|
||||||
const p = path.split('assets/icons/svg/')[1].split('.svg')[0];
|
const p = path.split('assets/icons/svg/')[1].split('.svg')[0];
|
||||||
@@ -42,7 +36,7 @@ function filterIcons() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectedIcon(name) {
|
function selectedIcon(name: string) {
|
||||||
emit('selected', name)
|
emit('selected', name)
|
||||||
document.body.click()
|
document.body.click()
|
||||||
}
|
}
|
||||||
@@ -61,9 +55,11 @@ defineExpose({
|
|||||||
.icon-body {
|
.icon-body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
.icon-list {
|
.icon-list {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
@@ -72,6 +68,7 @@ defineExpose({
|
|||||||
width: 33%;
|
width: 33%;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: -0.15em;
|
vertical-align: -0.15em;
|
||||||
|
|||||||
@@ -1,26 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="{'hidden':hidden}" class="pagination-container">
|
<div :class="{ 'hidden': hidden }" class="pagination-container">
|
||||||
<el-pagination
|
<el-pagination :background="background" v-model:current-page="currentPage" v-model:page-size="pageSize"
|
||||||
:background="background"
|
:layout="layout" :page-sizes="pageSizes" :total="total" @size-change="handleSizeChange"
|
||||||
v-model:current-page="currentPage"
|
@current-change="handleCurrentChange" />
|
||||||
v-model:page-size="pageSize"
|
|
||||||
:layout="layout"
|
|
||||||
:page-sizes="pageSizes"
|
|
||||||
:total="total"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
@current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import {computed} from "vue";
|
import { computed, PropType } from "vue";
|
||||||
import {scrollTo} from '@/utils/scroll-to'
|
import { scrollTo } from '@/utils/scroll-to'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
total: {
|
total: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Number,
|
type: Number as PropType<number>,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
@@ -32,7 +25,7 @@ const props = defineProps({
|
|||||||
default: 20
|
default: 20
|
||||||
},
|
},
|
||||||
pageSizes: {
|
pageSizes: {
|
||||||
type: Array,
|
type: Array as PropType<number[]>,
|
||||||
default() {
|
default() {
|
||||||
return [10, 20, 30, 50]
|
return [10, 20, 30, 50]
|
||||||
}
|
}
|
||||||
@@ -55,18 +48,16 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits();
|
const emit = defineEmits(["update:page", "update:limit", "pagination"]);
|
||||||
|
|
||||||
const currentPage = computed({
|
const currentPage = computed<number | undefined>({
|
||||||
get() {
|
get: () => props.page,
|
||||||
return props.page
|
set: (value) => {
|
||||||
},
|
emit('update:page', value)
|
||||||
set(val) {
|
|
||||||
emit('update:page', val)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const pageSize = computed({
|
const pageSize = computed<number | undefined>({
|
||||||
get() {
|
get() {
|
||||||
return props.limit
|
return props.limit
|
||||||
},
|
},
|
||||||
@@ -75,15 +66,16 @@ const pageSize = computed({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleSizeChange(val) {
|
function handleSizeChange(val: number) {
|
||||||
emit('pagination', {page: currentPage, limit: val})
|
emit('pagination', { page: currentPage, limit: val })
|
||||||
if (props.autoScroll) {
|
if (props.autoScroll) {
|
||||||
scrollTo(0, 800)
|
scrollTo(0, 800)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCurrentChange(val) {
|
function handleCurrentChange(val: number) {
|
||||||
emit('pagination', {page: val, limit: props.pageSizes})
|
currentPage.value = val
|
||||||
|
emit('pagination', { page: val, limit: props.limit })
|
||||||
if (props.autoScroll) {
|
if (props.autoScroll) {
|
||||||
scrollTo(0, 800)
|
scrollTo(0, 800)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
|
<div ref="rightPanel" :class="{ show: show }" class="rightPanel-container">
|
||||||
<div class="rightPanel-background"/>
|
<div class="rightPanel-background" />
|
||||||
<div class="rightPanel">
|
<div class="rightPanel">
|
||||||
<div class="handle-button" :style="{'top':buttonTop+'px','background-color':theme}" @click="show=!show">
|
<div class="handle-button" :style="{ 'top': buttonTop + 'px', 'background-color': theme }" @click="show = !show">
|
||||||
<Close style="width: 1em; height: 1em;vertical-align: middle " v-show="show"/>
|
<Close style="width: 1em; height: 1em;vertical-align: middle " v-show="show" />
|
||||||
<Setting style="width:1em; height:1em;vertical-align: middle " v-show="!show"/>
|
<Setting style="width:1em; height:1em;vertical-align: middle " v-show="!show" />
|
||||||
</div>
|
</div>
|
||||||
<div class="rightPanel-items">
|
<div class="rightPanel-items">
|
||||||
<slot/>
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, onBeforeUnmount, onMounted, ref, watch} from "vue";
|
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
||||||
|
|
||||||
import {addClass, removeClass} from '@/utils/index'
|
import { addClass, removeClass } from '@/utils/index'
|
||||||
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
|
|
||||||
// 图标依赖
|
// 图标依赖
|
||||||
import {Close, Setting} from '@element-plus/icons-vue'
|
import { Close, Setting } from '@element-plus/icons-vue'
|
||||||
import {ElColorPicker} from "element-plus";
|
import { ElColorPicker } from "element-plus";
|
||||||
|
|
||||||
const {setting} =useStore()
|
const { setting } = useStore()
|
||||||
|
|
||||||
const props = defineProps({
|
const theme = computed(() => setting.theme)
|
||||||
|
const show = ref(false)
|
||||||
|
|
||||||
|
defineProps({
|
||||||
buttonTop: {
|
buttonTop: {
|
||||||
default: 250,
|
default: 250,
|
||||||
type: Number
|
type: Number
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const theme = computed(() =>setting.theme)
|
|
||||||
|
|
||||||
const show = ref(false)
|
|
||||||
|
|
||||||
watch(show, (value) => {
|
watch(show, (value) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
addEventClick()
|
addEventClick()
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle"/>
|
<svg-icon :icon-class="isFullscreen ? 'exit-fullscreen' : 'fullscreen'" @click="toggle" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import {useFullscreen} from '@vueuse/core'
|
import { useFullscreen } from '@vueuse/core'
|
||||||
import SvgIcon from '@/components/SvgIcon/index.vue'
|
import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||||
|
|
||||||
const {isFullscreen, enter, toggle} = useFullscreen();
|
const { isFullscreen, toggle } = useFullscreen();
|
||||||
</script>
|
</script>
|
||||||
@@ -5,12 +5,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item
|
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="(size || 'default') == item.value"
|
||||||
v-for="item of sizeOptions"
|
:command="item.value">
|
||||||
:key="item.value"
|
|
||||||
:disabled="(size || 'default') == item.value"
|
|
||||||
:command="item.value"
|
|
||||||
>
|
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@@ -20,8 +16,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
|
||||||
|
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
|
|||||||
@@ -8,9 +8,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, nextTick, watch} from "vue";
|
import {computed, watch} from "vue";
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
import {useRoute, useRouter} from "vue-router";
|
|
||||||
import {localStorage} from "@/utils/storage";
|
import {localStorage} from "@/utils/storage";
|
||||||
|
|
||||||
// 参考连接:https://juejin.cn/post/7024025899813044232#heading-1
|
// 参考连接:https://juejin.cn/post/7024025899813044232#heading-1
|
||||||
|
|||||||
@@ -1,44 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="el-tree-select">
|
<div class="el-tree-select">
|
||||||
<el-select
|
<el-select style="width: 100%" v-model="modelValue" ref="treeSelect" :filterable="true" :clearable="true"
|
||||||
style="width: 100%"
|
@clear="clearHandle" :filter-method="selectFilterData" :placeholder="placeholder">
|
||||||
v-model="modelValue"
|
|
||||||
ref="treeSelect"
|
|
||||||
:filterable="true"
|
|
||||||
:clearable="true"
|
|
||||||
@clear="clearHandle"
|
|
||||||
:filter-method="selectFilterData"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
>
|
|
||||||
<el-option :value="modelValue" :label="valueTitle">
|
<el-option :value="modelValue" :label="valueTitle">
|
||||||
<el-tree
|
<el-tree id="tree-option" ref="selectTree" :accordion="accordion" :data="options" :props="state.props"
|
||||||
id="tree-option"
|
:node-key="state.props.value" :expand-on-click-node="false" :default-expanded-keys="defaultExpandedKey"
|
||||||
ref="selectTree"
|
:filter-node-method="filterNode" @node-click="handleNodeClick"></el-tree>
|
||||||
:accordion="accordion"
|
|
||||||
:data="options"
|
|
||||||
:props="state.props"
|
|
||||||
:node-key="state.props.value"
|
|
||||||
:expand-on-click-node="false"
|
|
||||||
:default-expanded-keys="defaultExpandedKey"
|
|
||||||
:filter-node-method="filterNode"
|
|
||||||
@node-click="handleNodeClick"
|
|
||||||
></el-tree>
|
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
nextTick,
|
nextTick,
|
||||||
onMounted,
|
onMounted,
|
||||||
computed,
|
computed,
|
||||||
watch,
|
watch
|
||||||
} from "vue";
|
} from "vue";
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance() as any;
|
||||||
|
|
||||||
const state = defineProps({
|
const state = defineProps({
|
||||||
// 配置项
|
// 配置项
|
||||||
@@ -67,7 +50,9 @@ const state = defineProps({
|
|||||||
// 数据源
|
// 数据源
|
||||||
options: {
|
options: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: [],
|
default: () => {
|
||||||
|
return []
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// 提示文字
|
// 提示文字
|
||||||
placeholder: {
|
placeholder: {
|
||||||
@@ -87,9 +72,9 @@ const modelValue = computed({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
const valueTitle = ref("");
|
const valueTitle = ref("");
|
||||||
const defaultExpandedKey = ref([]);
|
const defaultExpandedKey = ref([] as any[]);
|
||||||
|
|
||||||
function handleNodeClick(node) {
|
function handleNodeClick(node: any) {
|
||||||
valueTitle.value = node[state.props.label];
|
valueTitle.value = node[state.props.label];
|
||||||
modelValue.value = node[state.props.value];
|
modelValue.value = node[state.props.value];
|
||||||
defaultExpandedKey.value = [];
|
defaultExpandedKey.value = [];
|
||||||
@@ -97,11 +82,11 @@ function handleNodeClick(node) {
|
|||||||
selectFilterData("");
|
selectFilterData("");
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectFilterData(val) {
|
function selectFilterData(val: any) {
|
||||||
proxy.$refs.selectTree.filter(val);
|
proxy.$refs.selectTree.filter(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterNode(value, data) {
|
function filterNode(value: any, data: any) {
|
||||||
if (!value) return true;
|
if (!value) return true;
|
||||||
return data[state.props["label"]].indexOf(value) !== -1;
|
return data[state.props["label"]].indexOf(value) !== -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,18 +28,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from "vue";
|
import { computed } from "vue";
|
||||||
import { Plus, Close } from "@element-plus/icons-vue";
|
import { Plus, Close } from "@element-plus/icons-vue";
|
||||||
import {
|
import {
|
||||||
ElMessage,
|
ElMessage,
|
||||||
ElUpload,
|
ElUpload,
|
||||||
UploadFile,
|
|
||||||
UploadRawFile,
|
UploadRawFile,
|
||||||
UploadRequestOptions,
|
UploadRequestOptions,
|
||||||
} from "element-plus";
|
} from "element-plus";
|
||||||
import { uploadFile, deleteFile } from "@/api/system/file";
|
import { uploadFile, deleteFile } from "@/api/system/file";
|
||||||
|
|
||||||
const uploadRef = ref(ElUpload);
|
|
||||||
const emit = defineEmits(["update:modelValue"]);
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -89,10 +87,9 @@ function handleRemove(fileUrl?: string) {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 在 before-upload 钩子中限制用户上传文件的格式和大小
|
* 在 before-upload 钩子中限制用户上传文件的格式和大小
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
function handleBeforeUpload(file: UploadRawFile) {
|
function handleBeforeUpload(file: UploadRawFile) {
|
||||||
const isJPG = file.type === "image/jpeg";
|
// const isJPG = file.type === "image/jpeg";
|
||||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||||
|
|
||||||
if (!isLt2M) {
|
if (!isLt2M) {
|
||||||
|
|||||||
@@ -1,28 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div style="border: 1px solid #ccc">
|
<div style="border: 1px solid #ccc">
|
||||||
<!-- 工具栏 -->
|
<!-- 工具栏 -->
|
||||||
<Toolbar
|
<Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" style="border-bottom: 1px solid #ccc" :mode="mode" />
|
||||||
:editorId="editorId"
|
|
||||||
:defaultConfig="toolbarConfig"
|
|
||||||
style="border-bottom: 1px solid #ccc"
|
|
||||||
/>
|
|
||||||
<!-- 编辑器 -->
|
<!-- 编辑器 -->
|
||||||
<Editor
|
<Editor :defaultConfig="editorConfig" v-model="defaultHtml" @onChange="handleChange"
|
||||||
:editorId="editorId"
|
style="height: 500px; overflow-y: hidden;" :mode="mode" @onCreated="handleCreated" />
|
||||||
:defaultConfig="editorConfig"
|
|
||||||
:defaultHtml="defaultHtml"
|
|
||||||
@onChange="handleChange"
|
|
||||||
style="height: 500px; overflow-y: hidden;"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, onBeforeUnmount, reactive, toRefs} from 'vue'
|
import { onBeforeUnmount, shallowRef, reactive, toRefs} from 'vue'
|
||||||
import {Editor, Toolbar, getEditor, removeEditor} from '@wangeditor/editor-for-vue'
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
|
||||||
|
|
||||||
// API 引用
|
// API 引用
|
||||||
import {uploadFile} from "@/api/system/file";
|
import { uploadFile } from "@/api/system/file";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
@@ -33,16 +24,18 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
|
// 编辑器实例,必须用 shallowRef
|
||||||
|
const editorRef = shallowRef()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
editorId: `w-e-${Math.random().toString().slice(-5)}`, //【注意】编辑器 id ,要全局唯一
|
|
||||||
toolbarConfig: {},
|
toolbarConfig: {},
|
||||||
editorConfig: {
|
editorConfig: {
|
||||||
placeholder: '请输入内容...',
|
placeholder: '请输入内容...',
|
||||||
MENU_CONF: {
|
MENU_CONF: {
|
||||||
uploadImage: {
|
uploadImage: {
|
||||||
// 自定义图片上传
|
// 自定义图片上传
|
||||||
// @link https://www.wangeditor.com/v5/guide/menu-config.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8A%9F%E8%83%BD
|
async customUpload(file: any, insertFn: any) {
|
||||||
async customUpload(file:any, insertFn:any) {
|
console.log("上传图片")
|
||||||
uploadFile(file).then(response => {
|
uploadFile(file).then(response => {
|
||||||
const url = response.data
|
const url = response.data
|
||||||
insertFn(url)
|
insertFn(url)
|
||||||
@@ -51,23 +44,28 @@ const state = reactive({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
defaultHtml: props.modelValue
|
defaultHtml: props.modelValue,
|
||||||
|
mode: 'default'
|
||||||
})
|
})
|
||||||
|
|
||||||
const {editorId, toolbarConfig, editorConfig,defaultHtml} = toRefs(state)
|
const { toolbarConfig, editorConfig, defaultHtml, mode } = toRefs(state)
|
||||||
|
|
||||||
function handleChange(editor:any) {
|
const handleCreated = (editor: any) => {
|
||||||
|
editorRef.value = editor // 记录 editor 实例,重要!
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChange(editor: any) {
|
||||||
emit('update:modelValue', editor.getHtml())
|
emit('update:modelValue', editor.getHtml())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组件销毁时,也及时销毁编辑器
|
// 组件销毁时,也及时销毁编辑器
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
const editor = getEditor(state.editorId)
|
const editor = editorRef.value
|
||||||
if (editor == null) return
|
if (editor == null) return
|
||||||
editor.destroy()
|
editor.destroy()
|
||||||
removeEditor(state.editorId)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style src="@wangeditor/editor/dist/css/style.css"></style>
|
<style src="@wangeditor/editor/dist/css/style.css">
|
||||||
|
</style>
|
||||||
@@ -65,7 +65,6 @@ import Hamburger from "@/components/Hamburger/index.vue";
|
|||||||
import Screenfull from "@/components/Screenfull/index.vue";
|
import Screenfull from "@/components/Screenfull/index.vue";
|
||||||
import SizeSelect from "@/components/SizeSelect/index.vue";
|
import SizeSelect from "@/components/SizeSelect/index.vue";
|
||||||
import LangSelect from "@/components/LangSelect/index.vue";
|
import LangSelect from "@/components/LangSelect/index.vue";
|
||||||
import SvgIcon from "@/components/SvgIcon/index.vue";
|
|
||||||
|
|
||||||
// 图标依赖
|
// 图标依赖
|
||||||
import { CaretBottom } from "@element-plus/icons-vue";
|
import { CaretBottom } from "@element-plus/icons-vue";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sidebar-logo-container" :class="{'collapse':collapse}">
|
<div class="sidebar-logo-container" :class="{ 'collapse': isCollapse }">
|
||||||
<transition name="sidebarLogoFade">
|
<transition name="sidebarLogoFade">
|
||||||
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
|
||||||
<img v-if="logo" :src="logo" class="sidebar-logo">
|
<img v-if="logo" :src="logo" class="sidebar-logo">
|
||||||
@@ -14,17 +14,23 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref, reactive, toRefs } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
collapse: {
|
collapse: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const title=ref("vue3-element-admin")
|
const state = reactive({
|
||||||
const logo=ref("https://s2.loli.net/2022/04/07/hyquWXELOoYvlP6.png")
|
isCollapse: props.collapse
|
||||||
|
})
|
||||||
|
|
||||||
|
const { isCollapse } = toRefs(state)
|
||||||
|
|
||||||
|
const title = ref("vue3-element-admin")
|
||||||
|
const logo = ref("https://s2.loli.net/2022/04/07/hyquWXELOoYvlP6.png")
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -32,10 +38,12 @@ const logo=ref("https://s2.loli.net/2022/04/07/hyquWXELOoYvlP6.png")
|
|||||||
.sidebarLogoFade-enter-active {
|
.sidebarLogoFade-enter-active {
|
||||||
transition: opacity 1.5s;
|
transition: opacity 1.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarLogoFade-enter,
|
.sidebarLogoFade-enter,
|
||||||
.sidebarLogoFade-leave-to {
|
.sidebarLogoFade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-logo-container {
|
.sidebar-logo-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import path from 'path-browserify'
|
|
||||||
import { ref} from "vue";
|
import { ref} from "vue";
|
||||||
|
import path from 'path-browserify'
|
||||||
import {isExternal} from '@/utils/validate'
|
import {isExternal} from '@/utils/validate'
|
||||||
import AppLink from './Link.vue'
|
import AppLink from './Link.vue'
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ function hasOneShowingChild(children = [] as any, parent: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
};
|
}
|
||||||
|
|
||||||
function resolvePath(routePath: string) {
|
function resolvePath(routePath: string) {
|
||||||
if (isExternal(routePath)) {
|
if (isExternal(routePath)) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import {computed, defineComponent} from "vue";
|
import {computed} from "vue";
|
||||||
import {useRoute} from 'vue-router'
|
import {useRoute} from 'vue-router'
|
||||||
|
|
||||||
import SidebarItem from './SidebarItem.vue'
|
import SidebarItem from './SidebarItem.vue'
|
||||||
@@ -44,7 +44,7 @@ const activeMenu = computed(() => {
|
|||||||
const {meta, path} = route
|
const {meta, path} = route
|
||||||
// if set path, the sidebar will highlight the path you set
|
// if set path, the sidebar will highlight the path you set
|
||||||
if (meta.activeMenu) {
|
if (meta.activeMenu) {
|
||||||
return meta.activeMenu
|
return meta.activeMenu as string
|
||||||
}
|
}
|
||||||
return path
|
return path
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,12 +15,11 @@ import {
|
|||||||
computed,
|
computed,
|
||||||
onMounted,
|
onMounted,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
getCurrentInstance,
|
getCurrentInstance
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { TagView } from "@/types";
|
import { TagView } from "@/types";
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
|
|
||||||
const emits = defineEmits();
|
|
||||||
|
|
||||||
const tagAndTagSpacing = ref(4);
|
const tagAndTagSpacing = ref(4);
|
||||||
const scrollContainerRef = ref(null);
|
const scrollContainerRef = ref(null);
|
||||||
@@ -29,9 +28,6 @@ const { tagsView } = useStore();
|
|||||||
|
|
||||||
const visitedViews = computed(() => tagsView.visitedViews);
|
const visitedViews = computed(() => tagsView.visitedViews);
|
||||||
|
|
||||||
const emitScroll = () => {
|
|
||||||
(emits as any)("scroll");
|
|
||||||
};
|
|
||||||
|
|
||||||
const { ctx } = getCurrentInstance() as any;
|
const { ctx } = getCurrentInstance() as any;
|
||||||
const scrollWrapper = computed(() => {
|
const scrollWrapper = computed(() => {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
class="el-icon-close"
|
class="el-icon-close"
|
||||||
@click.prevent.stop="closeSelectedTag(tag)"
|
@click.prevent.stop="closeSelectedTag(tag)"
|
||||||
>
|
>
|
||||||
<close
|
<Close
|
||||||
class="el-icon-close"
|
class="el-icon-close"
|
||||||
style="width: 1em; height: 1em; vertical-align: middle"
|
style="width: 1em; height: 1em; vertical-align: middle"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -5,16 +5,16 @@
|
|||||||
class="drawer-bg"
|
class="drawer-bg"
|
||||||
@click="handleClickOutside"
|
@click="handleClickOutside"
|
||||||
/>
|
/>
|
||||||
<sidebar class="sidebar-container" />
|
<Sidebar class="sidebar-container" />
|
||||||
<div :class="{ hasTagsView: needTagsView }" class="main-container">
|
<div :class="{ hasTagsView: needTagsView }" class="main-container">
|
||||||
<div :class="{ 'fixed-header': fixedHeader }">
|
<div :class="{ 'fixed-header': fixedHeader }">
|
||||||
<navbar />
|
<navbar />
|
||||||
<tags-view v-if="needTagsView" />
|
<tags-view v-if="needTagsView" />
|
||||||
</div>
|
</div>
|
||||||
<app-main />
|
<app-main />
|
||||||
<right-panel v-if="showSettings">
|
<RightPanel v-if="showSettings">
|
||||||
<settings />
|
<settings />
|
||||||
</right-panel>
|
</RightPanel>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -28,7 +28,7 @@ import RightPanel from "@/components/RightPanel/index.vue";
|
|||||||
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
|
|
||||||
const { width, height } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
const WIDTH = 992;
|
const WIDTH = 992;
|
||||||
|
|
||||||
const { app, setting } = useStore();
|
const { app, setting } = useStore();
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ const usePermissionStore = defineStore({
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
listRoutes().then(response => {
|
listRoutes().then(response => {
|
||||||
const asyncRoutes = response.data
|
const asyncRoutes = response.data
|
||||||
let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
|
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
|
||||||
this.setRoutes(accessedRoutes)
|
this.setRoutes(accessedRoutes)
|
||||||
resolve(accessedRoutes)
|
resolve(accessedRoutes)
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ const useTagsViewStore = defineStore({
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
delAllViews(view: any) {
|
delAllViews() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const affixTags = this.visitedViews.filter(tag => tag.meta?.affix)
|
const affixTags = this.visitedViews.filter(tag => tag.meta?.affix)
|
||||||
this.visitedViews = affixTags
|
this.visitedViews = affixTags
|
||||||
|
|||||||
@@ -23,8 +23,6 @@
|
|||||||
--el-button-text-color: var(--el-color-white) !important;
|
--el-button-text-color: var(--el-color-white) !important;
|
||||||
--el-button-bg-color: var(--el-color-primary) !important;
|
--el-button-bg-color: var(--el-color-primary) !important;
|
||||||
--el-button-border-color: var(--el-color-primary) !important;
|
--el-button-border-color: var(--el-color-primary) !important;
|
||||||
--el-button-hover-bg-color: var(--el-color-primary-light-2) !important;
|
|
||||||
--el-button-hover-border-color: var(--el-color-primary-light-2) !important;
|
|
||||||
--el-button-active-bg-color: var(--el-color-primary-dark) !important;
|
--el-button-active-bg-color: var(--el-color-primary-dark) !important;
|
||||||
--el-button-active-border-color: var(--el-color-primary-dark) !important;
|
--el-button-active-border-color: var(--el-color-primary-dark) !important;
|
||||||
}
|
}
|
||||||
@@ -34,8 +32,6 @@
|
|||||||
--el-button-bg-color: var(--el-color-primary-light-9)!important;
|
--el-button-bg-color: var(--el-color-primary-light-9)!important;
|
||||||
--el-button-border-color: var(--el-color-primary-light-5)!important;
|
--el-button-border-color: var(--el-color-primary-light-5)!important;
|
||||||
--el-button-hover-text-color: var(--el-color-white)!important;
|
--el-button-hover-text-color: var(--el-color-white)!important;
|
||||||
--el-button-hover-bg-color: var(--el-color-primary)!important;
|
|
||||||
--el-button-hover-border-color: var(--el-color-primary)!important;
|
|
||||||
--el-button-active-text-color: var(--el-color-white)!important;
|
--el-button-active-text-color: var(--el-color-white)!important;
|
||||||
--el-button-active-border-color: var(--el-color-primary)!important;
|
--el-button-active-border-color: var(--el-color-primary)!important;
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/types/api/oms/order.d.ts
vendored
4
src/types/api/oms/order.d.ts
vendored
@@ -38,9 +38,7 @@ export interface OrderItem {
|
|||||||
/**
|
/**
|
||||||
* 订单分页项类型声明
|
* 订单分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface OrderPageResult extends PageResult<Order[]> {
|
export type OrderPageResult = PageResult<Order[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单表单类型声明
|
* 订单表单类型声明
|
||||||
|
|||||||
6
src/types/api/pms/brand.d.ts
vendored
6
src/types/api/pms/brand.d.ts
vendored
@@ -4,7 +4,7 @@ import { PageQueryParam, PageResult } from "../base"
|
|||||||
* 品牌查询参数类型声明
|
* 品牌查询参数类型声明
|
||||||
*/
|
*/
|
||||||
export interface BrandQueryParam extends PageQueryParam {
|
export interface BrandQueryParam extends PageQueryParam {
|
||||||
name: String | undefined
|
name?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -21,9 +21,7 @@ export interface BrandItem {
|
|||||||
/**
|
/**
|
||||||
* 品牌分页项类型声明
|
* 品牌分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface BrandPageResult extends PageResult<BrandItem[]> {
|
export type BrandPageResult = PageResult<BrandItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 品牌表单类型声明
|
* 品牌表单类型声明
|
||||||
|
|||||||
35
src/types/api/pms/goods.d.ts
vendored
35
src/types/api/pms/goods.d.ts
vendored
@@ -1,12 +1,11 @@
|
|||||||
import { PageQueryParam, PageResult } from "../base"
|
import { PageQueryParam, PageResult } from "../base"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品查询参数类型声明
|
* 商品查询参数类型声明
|
||||||
*/
|
*/
|
||||||
export interface GoodsQueryParam extends PageQueryParam {
|
export interface GoodsQueryParam extends PageQueryParam {
|
||||||
name: stirng | undefined,
|
name?: stirng,
|
||||||
categoryId: number | undefined
|
categoryId?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,25 +48,25 @@ export interface SkuItem {
|
|||||||
/**
|
/**
|
||||||
* 商品分页项类型声明
|
* 商品分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface GoodsPageResult extends PageResult<GoodsItem[]> {
|
export type GoodsPageResult = PageResult<GoodsItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品表单数据类型声明
|
* 商品表单数据类型声明
|
||||||
*/
|
*/
|
||||||
export interface GoodsFormData {
|
export interface GoodsDetail {
|
||||||
id: number|undefined,
|
id: string,
|
||||||
deptId: number,
|
name: string,
|
||||||
username: string,
|
categoryId: string,
|
||||||
nickname: string,
|
brandId: string,
|
||||||
password: string,
|
originPrice: number,
|
||||||
mobile: string,
|
price: number,
|
||||||
email: string,
|
picUrl: string,
|
||||||
gender: number,
|
album: string[],
|
||||||
status: number,
|
description: string,
|
||||||
remark: string,
|
detail: string,
|
||||||
roleIds: number[]
|
attrList: any[],
|
||||||
|
specList: any[],
|
||||||
|
skuList: any[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
8
src/types/api/sms/advert.d.ts
vendored
8
src/types/api/sms/advert.d.ts
vendored
@@ -4,7 +4,7 @@ import { PageQueryParam, PageResult } from "../base"
|
|||||||
* 广告查询参数类型声明
|
* 广告查询参数类型声明
|
||||||
*/
|
*/
|
||||||
export interface AdvertQueryParam extends PageQueryParam {
|
export interface AdvertQueryParam extends PageQueryParam {
|
||||||
title: String | undefined
|
title?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,15 +20,13 @@ export interface AdvertItem {
|
|||||||
/**
|
/**
|
||||||
* 广告分页项类型声明
|
* 广告分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface AdvertPageResult extends PageResult<AdvertItem[]> {
|
export type AdvertPageResult = PageResult<AdvertItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 广告表单类型声明
|
* 广告表单类型声明
|
||||||
*/
|
*/
|
||||||
export interface AdvertFormData {
|
export interface AdvertFormData {
|
||||||
id: number | undefined;
|
id?: number;
|
||||||
title: string;
|
title: string;
|
||||||
picUrl: string;
|
picUrl: string;
|
||||||
beginTime: string;
|
beginTime: string;
|
||||||
|
|||||||
4
src/types/api/system/client.d.ts
vendored
4
src/types/api/system/client.d.ts
vendored
@@ -31,9 +31,7 @@ export interface ClientItem {
|
|||||||
/**
|
/**
|
||||||
* 客户端分页项类型声明
|
* 客户端分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface ClientPageResult extends PageResult<ClientItem[]> {
|
export type ClientPageResult = PageResult<ClientItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 客户端表单类型声明
|
* 客户端表单类型声明
|
||||||
|
|||||||
13
src/types/api/system/dict.d.ts
vendored
13
src/types/api/system/dict.d.ts
vendored
@@ -25,9 +25,7 @@ export interface Dict {
|
|||||||
/**
|
/**
|
||||||
* 字典分页项类型声明
|
* 字典分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface DictPageResult extends PageResult<Dict[]> {
|
export type DictPageResult = PageResult<Dict[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典表单类型声明
|
* 字典表单类型声明
|
||||||
@@ -71,16 +69,15 @@ export interface DictItem {
|
|||||||
/**
|
/**
|
||||||
* 字典分页项类型声明
|
* 字典分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface DictItemPageResult extends PageResult<DictItem[]> {
|
export type DictItemPageResult = PageResult<DictItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典表单类型声明
|
* 字典表单类型声明
|
||||||
*/
|
*/
|
||||||
export interface DictItemFormData {
|
export interface DictItemFormData {
|
||||||
id: number | undefined;
|
id?: number;
|
||||||
dictCode:string,
|
dictCode?:string,
|
||||||
|
dictName?:string;
|
||||||
name: string;
|
name: string;
|
||||||
code: string;
|
code: string;
|
||||||
value: string;
|
value: string;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
/**
|
/**
|
||||||
* 菜单查询参数类型声明
|
* 菜单查询参数类型声明
|
||||||
*/
|
*/
|
||||||
export interface MenuQueryParam {
|
export interface MenuQueryParam {
|
||||||
name: String | undefined
|
name?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
4
src/types/api/system/perm.d.ts
vendored
4
src/types/api/system/perm.d.ts
vendored
@@ -23,9 +23,7 @@ export interface PermItem {
|
|||||||
/**
|
/**
|
||||||
* 权限分页项类型声明
|
* 权限分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface PermPageResult extends PageResult<PermItem[]> {
|
export type PermPageResult = PageResult<PermItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限表单类型声明
|
* 权限表单类型声明
|
||||||
|
|||||||
6
src/types/api/system/role.d.ts
vendored
6
src/types/api/system/role.d.ts
vendored
@@ -4,7 +4,7 @@ import { PageQueryParam, PageResult } from "../base"
|
|||||||
* 角色查询参数类型声明
|
* 角色查询参数类型声明
|
||||||
*/
|
*/
|
||||||
export interface RoleQueryParam extends PageQueryParam {
|
export interface RoleQueryParam extends PageQueryParam {
|
||||||
name: String | undefined
|
name?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,9 +25,7 @@ export interface RoleItem {
|
|||||||
/**
|
/**
|
||||||
* 角色分页项类型声明
|
* 角色分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface RolePageResult extends PageResult<RoleItem[]> {
|
export type RolePageResult = PageResult<RoleItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色表单类型声明
|
* 角色表单类型声明
|
||||||
|
|||||||
13
src/types/api/system/user.d.ts
vendored
13
src/types/api/system/user.d.ts
vendored
@@ -14,9 +14,9 @@ export interface UserInfo {
|
|||||||
* 用户查询参数类型声明
|
* 用户查询参数类型声明
|
||||||
*/
|
*/
|
||||||
export interface UserQueryParam extends PageQueryParam {
|
export interface UserQueryParam extends PageQueryParam {
|
||||||
keywords: String | undefined,
|
keywords: string,
|
||||||
status: number | undefined,
|
status: number,
|
||||||
deptId: number | undefined
|
deptId: number
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,9 +39,7 @@ export interface UserItem {
|
|||||||
/**
|
/**
|
||||||
* 用户分页项类型声明
|
* 用户分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface UserPageResult extends PageResult<UserItem[]> {
|
export type UserPageResult = PageResult<UserItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户表单类型声明
|
* 用户表单类型声明
|
||||||
@@ -60,11 +58,10 @@ export interface UserFormData {
|
|||||||
roleIds: number[]
|
roleIds: number[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户导入表单类型声明
|
* 用户导入表单类型声明
|
||||||
*/
|
*/
|
||||||
export interface UserImportFormData {
|
export interface UserImportFormData {
|
||||||
deptId: number,
|
deptId: number,
|
||||||
roleIds: number[]
|
roleIds: number[]
|
||||||
}
|
}
|
||||||
6
src/types/api/ums/member.d.ts
vendored
6
src/types/api/ums/member.d.ts
vendored
@@ -4,7 +4,7 @@ import { PageQueryParam, PageResult } from "../base"
|
|||||||
* 会员查询参数类型声明
|
* 会员查询参数类型声明
|
||||||
*/
|
*/
|
||||||
export interface MemberQueryParam extends PageQueryParam {
|
export interface MemberQueryParam extends PageQueryParam {
|
||||||
nickName: String | undefined
|
nickName?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,9 +46,7 @@ export interface AddressItem {
|
|||||||
/**
|
/**
|
||||||
* 会员分页项类型声明
|
* 会员分页项类型声明
|
||||||
*/
|
*/
|
||||||
export interface MemberPageResult extends PageResult<MemberItem[]> {
|
export type MemberPageResult = PageResult<MemberItem[]>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会员表单类型声明
|
* 会员表单类型声明
|
||||||
|
|||||||
@@ -31,17 +31,17 @@ export function removeClass(ele: HTMLElement, cls: string) {
|
|||||||
|
|
||||||
export function mix(color1: string, color2: string, weight: number) {
|
export function mix(color1: string, color2: string, weight: number) {
|
||||||
weight = Math.max(Math.min(Number(weight), 1), 0);
|
weight = Math.max(Math.min(Number(weight), 1), 0);
|
||||||
let r1 = parseInt(color1.substring(1, 3), 16);
|
const r1 = parseInt(color1.substring(1, 3), 16);
|
||||||
let g1 = parseInt(color1.substring(3, 5), 16);
|
const g1 = parseInt(color1.substring(3, 5), 16);
|
||||||
let b1 = parseInt(color1.substring(5, 7), 16);
|
const b1 = parseInt(color1.substring(5, 7), 16);
|
||||||
let r2 = parseInt(color2.substring(1, 3), 16);
|
const r2 = parseInt(color2.substring(1, 3), 16);
|
||||||
let g2 = parseInt(color2.substring(3, 5), 16);
|
const g2 = parseInt(color2.substring(3, 5), 16);
|
||||||
let b2 = parseInt(color2.substring(5, 7), 16);
|
const b2 = parseInt(color2.substring(5, 7), 16);
|
||||||
let r = Math.round(r1 * (1 - weight) + r2 * weight);
|
const r = Math.round(r1 * (1 - weight) + r2 * weight);
|
||||||
let g = Math.round(g1 * (1 - weight) + g2 * weight);
|
const g = Math.round(g1 * (1 - weight) + g2 * weight);
|
||||||
let b = Math.round(b1 * (1 - weight) + b2 * weight);
|
const b = Math.round(b1 * (1 - weight) + b2 * weight);
|
||||||
const rStr = ("0" + (r || 0).toString(16)).slice(-2);
|
const rStr = ("0" + (r || 0).toString(16)).slice(-2);
|
||||||
const gStr = ("0" + (g || 0).toString(16)).slice(-2);
|
const gStr = ("0" + (g || 0).toString(16)).slice(-2);
|
||||||
const bStr = ("0" + (b || 0).toString(16)).slice(-2);
|
const bStr = ("0" + (b || 0).toString(16)).slice(-2);
|
||||||
return "#" + rStr + gStr + bStr;
|
return "#" + rStr + gStr + bStr;
|
||||||
};
|
}
|
||||||
|
|||||||
@@ -52,10 +52,6 @@ service.interceptors.response.use(
|
|||||||
localStorage.clear(); // 清除浏览器全部缓存
|
localStorage.clear(); // 清除浏览器全部缓存
|
||||||
window.location.href = '/'; // 跳转登录页
|
window.location.href = '/'; // 跳转登录页
|
||||||
ElMessageBox.alert('当前页面已失效,请重新登录', '提示', {})
|
ElMessageBox.alert('当前页面已失效,请重新登录', '提示', {})
|
||||||
.then(() => {
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
ElMessage({
|
ElMessage({
|
||||||
message: msg || '系统出错',
|
message: msg || '系统出错',
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const position = () => {
|
|||||||
* @param {number} duration
|
* @param {number} duration
|
||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
export const scrollTo = (to: number, duration: number, callback?: Function) => {
|
export const scrollTo = (to: number, duration: number, callback?: any) => {
|
||||||
const start = position()
|
const start = position()
|
||||||
const change = to - start
|
const change = to - start
|
||||||
const increment = 20
|
const increment = 20
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const localStorage = {
|
|||||||
},
|
},
|
||||||
// 获取永久缓存
|
// 获取永久缓存
|
||||||
get(key: string) {
|
get(key: string) {
|
||||||
let json: any = window.localStorage.getItem(key);
|
const json: any = window.localStorage.getItem(key);
|
||||||
return JSON.parse(json);
|
return JSON.parse(json);
|
||||||
},
|
},
|
||||||
// 移除永久缓存
|
// 移除永久缓存
|
||||||
@@ -31,7 +31,7 @@ export const sessionStorage = {
|
|||||||
},
|
},
|
||||||
// 获取临时缓存
|
// 获取临时缓存
|
||||||
get(key: string) {
|
get(key: string) {
|
||||||
let json: any = window.sessionStorage.getItem(key);
|
const json: any = window.sessionStorage.getItem(key);
|
||||||
return JSON.parse(json);
|
return JSON.parse(json);
|
||||||
},
|
},
|
||||||
// 移除临时缓存
|
// 移除临时缓存
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
import {nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted} from "vue";
|
import {nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted} from "vue";
|
||||||
import {init, EChartsOption} from 'echarts'
|
import {init, EChartsOption} from 'echarts'
|
||||||
import resize from "@/utils/resize";
|
import resize from "@/utils/resize";
|
||||||
import * as echarts from "echarts";
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<el-tabs v-model="teamActiveName">
|
<el-tabs v-model="teamActiveName">
|
||||||
<el-tab-pane label="开发者「无回」" name="developer">
|
<el-tab-pane label="开发者「无回」" name="developer">
|
||||||
<div class="developer" ref="dev_wapper">
|
<div class="developer" ref="dev_wrapper">
|
||||||
<ul class="developer__container">
|
<ul class="developer__container">
|
||||||
<li class="developer__item" v-for="(item, index) in developers" :key="index">
|
<li class="developer__item" v-for="(item, index) in developers" :key="index">
|
||||||
<div class="developer__inner">
|
<div class="developer__inner">
|
||||||
@@ -21,9 +21,10 @@
|
|||||||
<div class="developer__position">
|
<div class="developer__position">
|
||||||
<el-tag
|
<el-tag
|
||||||
v-for="(position, i) in item.positions"
|
v-for="(position, i) in item.positions"
|
||||||
:type="colors[i % colors.length]"
|
:type="(colors[i % colors.length] as any)"
|
||||||
:class="i !== 0 ? 'f-ml' : ''"
|
:class="i !== 0 ? 'f-ml' : ''"
|
||||||
size="small"
|
size="small"
|
||||||
|
:key="i"
|
||||||
>{{ position }}</el-tag>
|
>{{ position }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
<div class="developer__homepage">
|
<div class="developer__homepage">
|
||||||
@@ -41,8 +42,8 @@
|
|||||||
<div class="group">
|
<div class="group">
|
||||||
<el-image
|
<el-image
|
||||||
class="group-img"
|
class="group-img"
|
||||||
src="https://cdn.youlai.tech/youlaiqun.png"
|
src="https://www.youlai.tech/files/blog/youlaiqun.png"
|
||||||
:preview-src-list="['https://cdn.youlai.tech/youlaiqun.png']"
|
:preview-src-list="['https://www.youlai.tech/files/blog/youlaiqun.png']"
|
||||||
/>
|
/>
|
||||||
<div class="group-tip">群二维码过期可添加开发者微信由其拉入群,备注「有来」即可。</div>
|
<div class="group-tip">群二维码过期可添加开发者微信由其拉入群,备注「有来」即可。</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,10 +100,10 @@ const { teamActiveName, developers, colors, indicatorImgUrl } = toRefs(state);
|
|||||||
|
|
||||||
let bScroll = reactive({})
|
let bScroll = reactive({})
|
||||||
|
|
||||||
const dev_wapper = ref<HTMLElement | any>(null)
|
const dev_wrapper = ref<HTMLElement | any>(null)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
bScroll = new BScroll(dev_wapper.value, {
|
bScroll = new BScroll(dev_wrapper.value, {
|
||||||
mouseWheel: true,//开启鼠标滚轮
|
mouseWheel: true,//开启鼠标滚轮
|
||||||
disableMouse: false,//启用鼠标拖动
|
disableMouse: false,//启用鼠标拖动
|
||||||
scrollX: true, //X轴滚动启用
|
scrollX: true, //X轴滚动启用
|
||||||
|
|||||||
@@ -86,68 +86,32 @@
|
|||||||
<!-- Echarts 图表 -->
|
<!-- Echarts 图表 -->
|
||||||
<el-row :gutter="40" style="margin-top: 20px">
|
<el-row :gutter="40" style="margin-top: 20px">
|
||||||
<el-col :sm="24" :lg="8" class="card-panel-col">
|
<el-col :sm="24" :lg="8" class="card-panel-col">
|
||||||
<BarChart
|
<BarChart id="barChart" height="400px" width="100%" class="chart-container" />
|
||||||
id="barChart"
|
|
||||||
height="400px"
|
|
||||||
width="100%"
|
|
||||||
class="chart-container"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
||||||
<PieChart
|
<PieChart id="pieChart" height="400px" width="100%" class="chart-container" />
|
||||||
id="pieChart"
|
|
||||||
height="400px"
|
|
||||||
width="100%"
|
|
||||||
class="chart-container"
|
|
||||||
/>
|
|
||||||
<!--订单漏斗图-->
|
<!--订单漏斗图-->
|
||||||
<!--<FunnelChart id="funnelChart" height="400px" width="100%" class="chart-container"/>-->
|
<!--<FunnelChart id="funnelChart" height="400px" width="100%" class="chart-container"/>-->
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
<el-col :xs="24" :sm="12" :lg="8" class="card-panel-col">
|
||||||
<RadarChart
|
<RadarChart id="radarChart" height="400px" width="100%" class="chart-container" />
|
||||||
id="radarChart"
|
|
||||||
height="400px"
|
|
||||||
width="100%"
|
|
||||||
class="chart-container"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// Vue引用
|
|
||||||
import {
|
|
||||||
computed,
|
|
||||||
nextTick,
|
|
||||||
onMounted,
|
|
||||||
reactive,
|
|
||||||
toRefs,
|
|
||||||
watchEffect,
|
|
||||||
} from "vue";
|
|
||||||
|
|
||||||
// 组件引用
|
// 组件引用
|
||||||
import GithubCorner from "@/components/GithubCorner/index.vue";
|
import GithubCorner from "@/components/GithubCorner/index.vue";
|
||||||
import SvgIcon from "@/components/SvgIcon/index.vue";
|
import SvgIcon from "@/components/SvgIcon/index.vue";
|
||||||
import BarChart from "./components/Chart/BarChart.vue";
|
import BarChart from "./components/Chart/BarChart.vue";
|
||||||
import PieChart from "./components/Chart/PieChart.vue";
|
import PieChart from "./components/Chart/PieChart.vue";
|
||||||
import RadarChart from "./components/Chart/RadarChart.vue";
|
import RadarChart from "./components/Chart/RadarChart.vue";
|
||||||
import FunnelChart from "./components/Chart/FunnelChart.vue";
|
|
||||||
|
|
||||||
import Project from "./components/Project/index.vue";
|
import Project from "./components/Project/index.vue";
|
||||||
import Team from "./components/Team/index.vue";
|
import Team from "./components/Team/index.vue";
|
||||||
|
|
||||||
import BScroll from "better-scroll";
|
|
||||||
|
|
||||||
import useStore from "@/store";
|
|
||||||
|
|
||||||
const { user } = useStore();
|
|
||||||
|
|
||||||
const roles = computed(() => user.roles);
|
|
||||||
const avatar = computed(() => user.avatar);
|
|
||||||
const nickname = computed(() => user.nickname);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
@@ -171,8 +135,7 @@ const nickname = computed(() => user.nickname);
|
|||||||
}
|
}
|
||||||
|
|
||||||
.user-profile {
|
.user-profile {
|
||||||
.user-name {
|
.user-name {}
|
||||||
}
|
|
||||||
|
|
||||||
.box-center {
|
.box-center {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
passwordType: "password",
|
passwordType: "password",
|
||||||
redirect: "",
|
|
||||||
captchaBase64: "",
|
captchaBase64: "",
|
||||||
// 大写提示禁用
|
// 大写提示禁用
|
||||||
capslockTooltipDisabled: true,
|
capslockTooltipDisabled: true,
|
||||||
@@ -164,7 +163,6 @@ const {
|
|||||||
loginRules,
|
loginRules,
|
||||||
loading,
|
loading,
|
||||||
passwordType,
|
passwordType,
|
||||||
redirect,
|
|
||||||
captchaBase64,
|
captchaBase64,
|
||||||
capslockTooltipDisabled,
|
capslockTooltipDisabled,
|
||||||
showCopyright,
|
showCopyright,
|
||||||
|
|||||||
@@ -118,10 +118,10 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm } from "element-plus";
|
||||||
import { Dialog, Order, OrderQueryParam } from "@/types";
|
import { Dialog, Order, OrderQueryParam } from "@/types";
|
||||||
import { listOrderPages, getOrderDetail } from "@/api/oms/order";
|
import { listOrderPages, getOrderDetail } from "@/api/oms/order";
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Refresh } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
const queryFormRef = ref(ElForm);
|
const queryFormRef = ref(ElForm);
|
||||||
|
|
||||||
@@ -196,14 +196,10 @@ const state = reactive({
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
single,
|
|
||||||
multiple,
|
|
||||||
queryParams,
|
queryParams,
|
||||||
orderList,
|
orderList,
|
||||||
total,
|
total,
|
||||||
dialog,
|
|
||||||
dateRange,
|
dateRange,
|
||||||
orderDetail,
|
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
@@ -227,9 +223,6 @@ function viewDetail(row: any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancel() {
|
|
||||||
state.dialog.visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handleQuery();
|
handleQuery();
|
||||||
|
|||||||
@@ -3,16 +3,8 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
>新增</el-button
|
<el-button type="danger" :icon="Delete" click="handleDelete" :disabled="multiple">删除</el-button>
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
click="handleDelete"
|
|
||||||
:disabled="multiple"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
@@ -20,20 +12,13 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetForm">重置</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<el-table v-loading="loading" :data="brandList" @selection-change="handleSelectionChange" border>
|
||||||
v-loading="loading"
|
|
||||||
:data="brandList"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" min-width="5%" />
|
<el-table-column type="selection" min-width="5%" />
|
||||||
<el-table-column prop="name" label="品牌名称" min-width="10" />
|
<el-table-column prop="name" label="品牌名称" min-width="10" />
|
||||||
<el-table-column prop="logoUrl" label="LOGO" min-width="10">
|
<el-table-column prop="logoUrl" label="LOGO" min-width="10">
|
||||||
@@ -41,10 +26,7 @@
|
|||||||
<el-popover placement="right" :width="400" trigger="hover">
|
<el-popover placement="right" :width="400" trigger="hover">
|
||||||
<img :src="scope.row.logoUrl" width="400" height="400" />
|
<img :src="scope.row.logoUrl" width="400" height="400" />
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<img
|
<img :src="scope.row.logoUrl" style="max-height: 60px; max-width: 60px" />
|
||||||
:src="scope.row.logoUrl"
|
|
||||||
style="max-height: 60px; max-width: 60px"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
@@ -54,46 +36,19 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" width="150">
|
<el-table-column label="操作" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button @click="handleUpdate(scope.row)" type="primary" :icon="Edit" circle plain />
|
||||||
@click="handleUpdate(scope.row)"
|
<el-button type="danger" :icon="Delete" circle plain @click="handleDelete(scope.row)" />
|
||||||
type="primary"
|
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页工具条 -->
|
<!-- 分页工具条 -->
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNum"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表单弹窗 -->
|
<!-- 表单弹窗 -->
|
||||||
<el-dialog
|
<el-dialog :title="dialog.title" v-model="dialog.visible" top="5vh" width="600px">
|
||||||
:title="dialog.title"
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
v-model="dialog.visible"
|
|
||||||
top="5vh"
|
|
||||||
width="600px"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="100px"
|
|
||||||
>
|
|
||||||
<el-form-item label="品牌名称" prop="name">
|
<el-form-item label="品牌名称" prop="name">
|
||||||
<el-input v-model="formData.name" auto-complete="off" />
|
<el-input v-model="formData.name" auto-complete="off" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -118,7 +73,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, toRefs, unref } from "vue";
|
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||||
import { ElForm, ElTable, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm, ElTable, ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||||
import { BrandFormData, BrandItem, BrandQueryParam, Dialog } from "@/types";
|
import { BrandFormData, BrandItem, BrandQueryParam, Dialog } from "@/types";
|
||||||
@@ -156,14 +111,13 @@ const state = reactive({
|
|||||||
required: true,
|
required: true,
|
||||||
message: "请输入品牌名称",
|
message: "请输入品牌名称",
|
||||||
trigger: "blur",
|
trigger: "blur",
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
queryParams,
|
queryParams,
|
||||||
brandList,
|
brandList,
|
||||||
@@ -211,17 +165,20 @@ function handleUpdate(row: any) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表单提交
|
||||||
|
*/
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
dataFormRef.value.validate((isValid: boolean) => {
|
dataFormRef.value.validate((isValid: boolean) => {
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateBrand(state.formData.id, state.formData).then((response) => {
|
updateBrand(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
cancel();
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addBrand(state.formData).then((response) => {
|
addBrand(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
cancel();
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
@@ -232,18 +189,16 @@ function submitForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置表单
|
* 取消
|
||||||
*/
|
*/
|
||||||
function resetForm() {
|
function cancel() {
|
||||||
state.formData.id = undefined;
|
state.dialog.visible = false;
|
||||||
dataFormRef.value.resetFields();
|
dataFormRef.value.resetFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
function cancel() {
|
/**
|
||||||
state.dialog.visible = false;
|
* 删除
|
||||||
resetForm();
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
function handleDelete(row: any) {
|
function handleDelete(row: any) {
|
||||||
const ids = [row.id || state.ids].join(",");
|
const ids = [row.id || state.ids].join(",");
|
||||||
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
|
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
|
||||||
|
|||||||
@@ -7,43 +7,21 @@
|
|||||||
<el-tag v-else type="info"><i class="el-icon-info"></i> 请选择商品分类</el-tag>
|
<el-tag v-else type="info"><i class="el-icon-info"></i> 请选择商品分类</el-tag>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" style="text-align: right">
|
<el-col :span="12" style="text-align: right">
|
||||||
<el-button type="primary" :icon="Check" @click="submitForm">提交</el-button>
|
<el-button type="primary" :icon="Check" @click="submitForm">提交</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row style="margin-top: 10px">
|
<el-row style="margin-top: 10px">
|
||||||
<el-form
|
<el-form ref="form" :model="formData" :disabled="category?.childrenLen > 0" label-width="100">
|
||||||
ref="form"
|
<el-form-item v-for="(item, index) in formData.attributes" :key="index" :label="attributeTypeName + (index + 1)"
|
||||||
:model="formData"
|
:prop="'attributes.' + index + '.name'" :rules="rules.attribute.name">
|
||||||
:disabled="category?.childrenLen>0"
|
<el-input v-model="item.name" style="width: 300px" />
|
||||||
label-width="100"
|
|
||||||
>
|
|
||||||
<el-form-item
|
|
||||||
v-for="(item, index) in formData.attributes"
|
|
||||||
:label="attributeTypeName + (index+1)"
|
|
||||||
:prop="'attributes.' + index + '.name'"
|
|
||||||
:rules="rules.attribute.name"
|
|
||||||
>
|
|
||||||
<el-input v-model="item.name" style="width: 300px"/>
|
|
||||||
|
|
||||||
<el-button
|
<el-button v-if="index === 0" type="success" :icon="Plus" circle plain @click.prevent="handleAdd()"
|
||||||
v-if="index===0"
|
style="margin-left: 15px" />
|
||||||
type="success"
|
|
||||||
:icon="Plus"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.prevent="handleAdd()"
|
|
||||||
style="margin-left: 15px"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<el-button
|
<el-button type="danger" :icon="Delete" plain circle @click.prevent="handleDelete(index)"
|
||||||
type="danger"
|
style="margin-left: 15px" />
|
||||||
:icon="Delete"
|
|
||||||
plain
|
|
||||||
circle
|
|
||||||
@click.prevent="handleDelete(index)"
|
|
||||||
style="margin-left: 15px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -52,11 +30,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {listAttributes, saveAttributeBatch} from "@/api/pms/attribute";
|
|
||||||
import {computed, reactive, toRefs, watch} from "vue";
|
|
||||||
import {Plus, Check, Delete} from '@element-plus/icons-vue'
|
import { computed, reactive, toRefs, watch } from "vue";
|
||||||
import {ElMessage} from "element-plus";
|
import { listAttributes, saveAttributeBatch } from "@/api/pms/attribute";
|
||||||
import SvgIcon from '@/components/SvgIcon/index.vue';
|
import { Plus, Check, Delete } from '@element-plus/icons-vue'
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
attributeType: {
|
attributeType: {
|
||||||
@@ -65,10 +44,12 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
category: {
|
category: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {
|
default: () => {
|
||||||
id: undefined,
|
return {
|
||||||
name: '',
|
id: undefined,
|
||||||
childrenLen: 0
|
name: '',
|
||||||
|
childrenLen: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -95,20 +76,20 @@ const state = reactive({
|
|||||||
rules: {
|
rules: {
|
||||||
attribute: {
|
attribute: {
|
||||||
name: [
|
name: [
|
||||||
{required: true, validator: attributeNameValidator, trigger: 'blur'}
|
{ required: true, validator: attributeNameValidator, trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const {formData, rules} = toRefs(state)
|
const { formData, rules } = toRefs(state)
|
||||||
|
|
||||||
watch(() => props.category.id as any, (newVal, oldVal) => {
|
watch(() => props.category.id as any, () => {
|
||||||
const categoryId = props.category.id
|
const categoryId = props.category.id
|
||||||
if (categoryId) {
|
if (categoryId) {
|
||||||
listAttributes({categoryId: categoryId,type:props.attributeType}).then(response => {
|
listAttributes({ categoryId: categoryId, type: props.attributeType }).then(response => {
|
||||||
|
|
||||||
const {data} = response
|
const { data } = response
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
state.formData.attributes = response.data
|
state.formData.attributes = response.data
|
||||||
} else {
|
} else {
|
||||||
@@ -156,8 +137,7 @@ function submitForm() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.component-container{
|
.component-container {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,83 +1,47 @@
|
|||||||
<!-- 商品分类层级最多为三层,level字段标识 -->
|
<!-- 商品分类层级最多为三层,level字段标识 -->
|
||||||
<template>
|
<template>
|
||||||
<div class="component-container">
|
<div class="component-container">
|
||||||
|
<el-tree v-loading="loading" ref="categoryTreeRef" :data="categoryOptions"
|
||||||
<el-tree
|
:props="{ label: 'name', children: 'children', disabled: '' }" node-key="id" :expand-on-click-node="false"
|
||||||
v-loading="loading"
|
default-expand-all :accordion="true" @node-click="handleNodeClick">
|
||||||
ref="categoryTreeRef"
|
|
||||||
:data="categoryOptions"
|
|
||||||
:props="{ label: 'name', children: 'children',disabled:'' }"
|
|
||||||
node-key="id"
|
|
||||||
:expand-on-click-node="false"
|
|
||||||
default-expand-all
|
|
||||||
:accordion="true"
|
|
||||||
@node-click="handleNodeClick"
|
|
||||||
>
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="custom-tree-node">
|
<div class="custom-tree-node">
|
||||||
<span>
|
<span>
|
||||||
<el-image
|
<el-image v-show="scope.data.level == 3" :src="scope.data.iconUrl"
|
||||||
v-show="scope.data.level == 3 "
|
style="width: 20px; height:20px; vertical-align: middle;margin-top: -5px">
|
||||||
:src="scope.data.iconUrl"
|
|
||||||
style="width: 20px; height:20px; vertical-align: middle;margin-top: -5px"
|
|
||||||
>
|
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="image-slot">
|
<div class="image-slot">
|
||||||
<Picture style="width: 20px; height:20px;"/>
|
<Picture style="width: 20px; height:20px;" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
{{ scope.data.name }}
|
{{ scope.data.name }}
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<el-button
|
<el-button v-show="scope.data.level != 3" type="success" :icon="Plus" circle plain
|
||||||
v-show="scope.data.level != 3 "
|
@click.stop="handleAdd(scope.data)" />
|
||||||
type="success"
|
<el-button v-show="scope.data.id !== 0" type="warning" :icon="Edit" circle plain
|
||||||
:icon="Plus"
|
@click.stop="handleUpdate(scope.data)" />
|
||||||
circle
|
<el-button v-show="scope.data.id && (!scope.data.children || scope.data.children.length <= 0)" type="danger"
|
||||||
plain
|
:icon="Delete" circle plain @click.stop="handleDelete(scope.data)" />
|
||||||
@click.stop="handleAdd(scope.data)"/>
|
</span>
|
||||||
<el-button
|
|
||||||
v-show="scope.data.id !== 0"
|
|
||||||
type="warning"
|
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleUpdate(scope.data)"/>
|
|
||||||
<el-button
|
|
||||||
v-show="scope.data.id && (!scope.data.children || scope.data.children.length <= 0)"
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleDelete(scope.data)"/>
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
|
|
||||||
<el-dialog
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="750px">
|
||||||
:title="dialog.title"
|
|
||||||
v-model="dialog.visible"
|
|
||||||
width="750px"
|
|
||||||
>
|
|
||||||
|
|
||||||
<el-form
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="100px"
|
|
||||||
>
|
|
||||||
<el-form-item label="上级分类" prop="parentId">
|
<el-form-item label="上级分类" prop="parentId">
|
||||||
<el-input v-model="parent.name" readonly/>
|
<el-input v-model="parent.name" readonly />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="分类名称" prop="name">
|
<el-form-item label="分类名称" prop="name">
|
||||||
<el-input v-model="formData.name"/>
|
<el-input v-model="formData.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="分类图标" prop="iconUrl">
|
<el-form-item label="分类图标" prop="iconUrl">
|
||||||
<single-upload v-model="formData.iconUrl"/>
|
<single-upload v-model="formData.iconUrl" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="显示状态" prop="visible">
|
<el-form-item label="显示状态" prop="visible">
|
||||||
@@ -103,11 +67,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {listCategories, addCategory, updateCategory, deleteCategories} from '@/api/pms/category'
|
import { listCategories, addCategory, updateCategory, deleteCategories } from '@/api/pms/category'
|
||||||
import {Search, Plus, Edit, Refresh, Delete} from '@element-plus/icons-vue'
|
import { Plus, Edit, Delete } from '@element-plus/icons-vue'
|
||||||
import SingleUpload from '@/components/Upload/SingleUpload.vue'
|
import SingleUpload from '@/components/Upload/SingleUpload.vue'
|
||||||
import {getCurrentInstance, onMounted, reactive, ref, toRefs, unref} from "vue";
|
import { onMounted, reactive, ref, toRefs, unref, defineEmits } from "vue";
|
||||||
import {ElForm, ElMessage, ElMessageBox, ElTree} from "element-plus";
|
import { ElForm, ElMessage, ElMessageBox, ElTree } from "element-plus";
|
||||||
|
|
||||||
const emit = defineEmits(['categoryClick'])
|
const emit = defineEmits(['categoryClick'])
|
||||||
|
|
||||||
@@ -145,7 +109,7 @@ const state = reactive({
|
|||||||
current: {} as any
|
current: {} as any
|
||||||
})
|
})
|
||||||
|
|
||||||
const {loading, categoryOptions, formData, rules, dialog, parent} = toRefs(state)
|
const { loading, categoryOptions, formData, rules, dialog, parent } = toRefs(state)
|
||||||
|
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
state.loading = true
|
state.loading = true
|
||||||
@@ -159,7 +123,6 @@ function handleQuery() {
|
|||||||
}]
|
}]
|
||||||
state.loading = false
|
state.loading = false
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNodeClick(row: any) {
|
function handleNodeClick(row: any) {
|
||||||
@@ -175,9 +138,7 @@ function handleNodeClick(row: any) {
|
|||||||
emit('categoryClick', row)
|
emit('categoryClick', row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleAdd(row: any) {
|
function handleAdd(row: any) {
|
||||||
resetForm()
|
|
||||||
state.dialog = {
|
state.dialog = {
|
||||||
title: '新增商品分类',
|
title: '新增商品分类',
|
||||||
visible: true
|
visible: true
|
||||||
@@ -192,7 +153,6 @@ function handleAdd(row: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleUpdate(row: any) {
|
function handleUpdate(row: any) {
|
||||||
resetForm()
|
|
||||||
handleNodeClick(row)
|
handleNodeClick(row)
|
||||||
state.dialog = {
|
state.dialog = {
|
||||||
title: '修改商品分类',
|
title: '修改商品分类',
|
||||||
@@ -202,24 +162,23 @@ function handleUpdate(row: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
const form = unref(dataFormRef)
|
dataFormRef.value.validate((valid: any) => {
|
||||||
form.validate((valid: any) => {
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateCategory(state.formData.id, state.formData).then(response => {
|
updateCategory(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success('修改成功')
|
ElMessage.success('修改成功')
|
||||||
state.dialog.visible = false
|
cancel()
|
||||||
handleQuery()
|
handleQuery()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const parentCategory= state.parent as any
|
const parentCategory = state.parent as any
|
||||||
console.log('parent',parentCategory)
|
console.log('parent', parentCategory)
|
||||||
state.formData.parentId = parentCategory.id
|
state.formData.parentId = parentCategory.id
|
||||||
state.formData.level = parentCategory.level+1
|
state.formData.level = parentCategory.level + 1
|
||||||
|
|
||||||
addCategory(state.formData).then(() => {
|
addCategory(state.formData).then(() => {
|
||||||
ElMessage.success('新增成功')
|
ElMessage.success('新增成功')
|
||||||
state.dialog.visible = false
|
cancel()
|
||||||
handleQuery()
|
handleQuery()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -241,20 +200,9 @@ function handleDelete(row: any) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
|
||||||
state.formData = {
|
|
||||||
id: undefined,
|
|
||||||
name: undefined,
|
|
||||||
parentId: 0,
|
|
||||||
level: undefined,
|
|
||||||
iconUrl: undefined,
|
|
||||||
visible: 1,
|
|
||||||
sort: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancel() {
|
function cancel() {
|
||||||
resetForm()
|
state.dialog.visible = false;
|
||||||
|
dataFormRef.value.resetFields();
|
||||||
state.dialog.visible = false
|
state.dialog.visible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<svg-icon icon-class="menu"/>
|
<svg-icon icon-class="menu"/>
|
||||||
商品分类
|
商品分类
|
||||||
</template>
|
</template>
|
||||||
<category ref="categoryRef" @categoryClick="handleCategoryClick"/>
|
<Category ref="categoryRef" @categoryClick="handleCategoryClick"/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@@ -18,9 +18,9 @@
|
|||||||
{{category.name}} 规格属性
|
{{category.name}} 规格属性
|
||||||
</template>
|
</template>
|
||||||
<!-- 商品规格 -->
|
<!-- 商品规格 -->
|
||||||
<attribute ref="specificationRef" :attributeType="1" :category="category"/>
|
<Attribute ref="specificationRef" :attributeType="1" :category="category"/>
|
||||||
<!-- 商品属性 -->
|
<!-- 商品属性 -->
|
||||||
<attribute ref="attributeRef" :attributeType="2" :category="category"/>
|
<Attribute ref="attributeRef" :attributeType="2" :category="category"/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|||||||
@@ -4,35 +4,15 @@
|
|||||||
<el-card class="box-card">
|
<el-card class="box-card">
|
||||||
<template #header>
|
<template #header>
|
||||||
<span>商品属性</span>
|
<span>商品属性</span>
|
||||||
<el-button
|
<el-button style="float: right" type="success" :icon="Plus" size="small" @click="handleAdd">
|
||||||
style="float: right"
|
|
||||||
type="success"
|
|
||||||
:icon="Plus"
|
|
||||||
size="small"
|
|
||||||
@click="handleAdd"
|
|
||||||
>
|
|
||||||
添加属性
|
添加属性
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-form
|
<el-form ref="dataFormRef" :model="goodsInfo" :rules="rules" size="small" :inline="true">
|
||||||
ref="dataForm"
|
<el-table :data="goodsInfo.attrList" size="small" highlight-current-row border>
|
||||||
:model="modelValue"
|
|
||||||
:rules="rules"
|
|
||||||
size="small"
|
|
||||||
:inline="true"
|
|
||||||
>
|
|
||||||
<el-table
|
|
||||||
:data="modelValue.attrList"
|
|
||||||
size="small"
|
|
||||||
highlight-current-row
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column property="name" label="属性名称">
|
<el-table-column property="name" label="属性名称">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item :prop="'attrList[' + scope.$index + '].name'" :rules="rules.name">
|
||||||
:prop="'attrList[' + scope.$index + '].name'"
|
|
||||||
:rules="rules.name"
|
|
||||||
>
|
|
||||||
<el-input v-model="scope.row.name" />
|
<el-input v-model="scope.row.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -40,10 +20,7 @@
|
|||||||
|
|
||||||
<el-table-column property="value" label="属性值">
|
<el-table-column property="value" label="属性值">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item :prop="'attrList[' + scope.$index + '].value'" :rules="rules.value">
|
||||||
:prop="'attrList[' + scope.$index + '].value'"
|
|
||||||
:rules="rules.value"
|
|
||||||
>
|
|
||||||
<el-input v-model="scope.row.value" />
|
<el-input v-model="scope.row.value" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -52,15 +29,8 @@
|
|||||||
<el-table-column label="操作" width="150">
|
<el-table-column label="操作" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button
|
<el-button v-if="scope.$index > 0" type="danger" :icon="Minus" size="small" circle plain
|
||||||
v-if="scope.$index > 0"
|
@click.stop="handleRemove(scope.$index)" />
|
||||||
type="danger"
|
|
||||||
:icon="Minus"
|
|
||||||
size="small"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleRemove(scope.$index)"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -70,60 +40,60 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="component-container__footer">
|
<div class="component-container__footer">
|
||||||
<el-button @click="handlePrev">上一步,填写商品信息</el-button>
|
<el-button @click="handlePrev">上一步,填写商品信息</el-button>
|
||||||
<el-button type="primary" @click="handleNext"
|
<el-button type="primary" @click="handleNext">下一步,设置商品库存</el-button>
|
||||||
>下一步,设置商品库存</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed, reactive, ref, toRefs, watch } from "vue";
|
||||||
import { listAttributes } from "@/api/pms/attribute";
|
import { listAttributes } from "@/api/pms/attribute";
|
||||||
import { computed, nextTick, reactive, ref, toRefs, unref, watch } from "vue";
|
|
||||||
import { ElForm } from "element-plus";
|
import { ElForm } from "element-plus";
|
||||||
import { Plus, Minus } from "@element-plus/icons-vue";
|
import { Plus, Minus } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
const emit = defineEmits(["prev", "next"]);
|
const emit = defineEmits(["prev", "next", "update:modelValue"]);
|
||||||
const dataForm = ref(ElForm);
|
const dataFormRef = ref(ElForm);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: () => { }
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const categoryId = computed(() => props.modelValue.categoryId);
|
const goodsInfo: any = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value) => {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
watch(
|
watch(() => goodsInfo.value.categoryId, (newVal) => {
|
||||||
categoryId,
|
// 商品编辑不加载分类下的属性
|
||||||
(newVal) => {
|
const goodsId = goodsInfo.value.id;
|
||||||
// 商品编辑不加载分类下的属性
|
if (goodsId) {
|
||||||
const spuId = props.modelValue.id;
|
return false;
|
||||||
if (spuId) {
|
}
|
||||||
return false;
|
// 商品新增加载默认分类下的属性
|
||||||
}
|
if (newVal) {
|
||||||
|
// type=2 商品分类下的属性
|
||||||
|
listAttributes({ categoryId: newVal, type: 2 }).then((response) => {
|
||||||
|
const attrList = response.data;
|
||||||
|
if (attrList && attrList.length > 0) {
|
||||||
|
goodsInfo.value.attrList = attrList;
|
||||||
|
} else {
|
||||||
|
goodsInfo.value.attrList = [{}];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
goodsInfo.value.attrList = [{}];
|
||||||
|
}
|
||||||
|
|
||||||
// 商品新增加载默认分类下的属性
|
},
|
||||||
if (newVal) {
|
|
||||||
// type=2 商品分类下的属性
|
|
||||||
listAttributes({ categoryId: newVal, type: 2 }).then((response) => {
|
|
||||||
const attrList = response.data;
|
|
||||||
if (attrList && attrList.length > 0) {
|
|
||||||
props.modelValue.attrList = attrList;
|
|
||||||
} else {
|
|
||||||
props.modelValue.attrList = [{}];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
props.modelValue.attrList = [{}];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true
|
||||||
}
|
})
|
||||||
);
|
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
rules: {
|
rules: {
|
||||||
@@ -135,11 +105,11 @@ const state = reactive({
|
|||||||
const { rules } = toRefs(state);
|
const { rules } = toRefs(state);
|
||||||
|
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
props.modelValue.attrList.push({});
|
goodsInfo.value.attrList.push({});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleRemove(index: number) {
|
function handleRemove(index: number) {
|
||||||
props.modelValue.attrList.splice(index, 1);
|
goodsInfo.value.attrList.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePrev() {
|
function handlePrev() {
|
||||||
@@ -147,8 +117,7 @@ function handlePrev() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleNext() {
|
function handleNext() {
|
||||||
const form = unref(dataForm);
|
dataFormRef.value.validate((valid: any) => {
|
||||||
form.validate((valid: any) => {
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
emit("next");
|
emit("next");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="component-container">
|
<div class="component-container">
|
||||||
<div class="component-container__main">
|
<div class="component-container__main">
|
||||||
<el-cascader-panel
|
<el-cascader-panel ref="categoryRef" :options="categoryOptions" v-model="goodsInfo.categoryId"
|
||||||
ref="categoryRef"
|
:props="{ emitPath: false }" @change="handleCategoryChange" />
|
||||||
:options="categoryOptions"
|
|
||||||
v-model="modelValue.categoryId"
|
|
||||||
:props="{emitPath:false}"
|
|
||||||
@change="handleCategoryChange"
|
|
||||||
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div style="margin-top: 20px">
|
<div style="margin-top: 20px">
|
||||||
<el-link type="info" :underline="false" v-show="pathLabels.length>0">您选择的商品分类:</el-link>
|
<el-link type="info" :underline="false" v-show="pathLabels.length > 0">您选择的商品分类:</el-link>
|
||||||
<el-link type="danger" :underline="false" v-for="(item,index) in pathLabels" style="margin-left: 5px">
|
<el-link type="danger" :underline="false" v-for="(item, index) in pathLabels" :key="index"
|
||||||
|
style="margin-left: 5px">
|
||||||
{{ item }}
|
{{ item }}
|
||||||
<CaretRight v-show="index<pathLabels.length-1" style="width: 1em; height:1em;margin-left: 5px"/>
|
<CaretRight v-show="index < pathLabels.length - 1" style="width: 1em; height:1em;margin-left: 5px" />
|
||||||
</el-link>
|
</el-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -26,18 +20,27 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {onMounted,nextTick, reactive, ref, toRefs} from "vue";
|
import { onMounted, nextTick, reactive, ref, toRefs } from "vue";
|
||||||
import {ElCascaderPanel, ElMessage} from "element-plus";
|
import { ElCascaderPanel, ElMessage } from "element-plus";
|
||||||
import {CaretRight} from '@element-plus/icons-vue';
|
import { CaretRight } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
// API 引用
|
// API 引用
|
||||||
import {listCascadeCategories} from "@/api/pms/category";
|
import { listCascadeCategories } from "@/api/pms/category";
|
||||||
|
import { computed } from "@vue/reactivity";
|
||||||
|
import { GoodsDetail } from "@/types";
|
||||||
|
|
||||||
const emit = defineEmits(['next'])
|
const emit = defineEmits(['next', "update:modelValue"])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default:{ }
|
default: () => { }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const goodsInfo: any = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value) => {
|
||||||
|
emit('update:modelValue', value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -46,12 +49,12 @@ const state = reactive({
|
|||||||
pathLabels: []
|
pathLabels: []
|
||||||
})
|
})
|
||||||
|
|
||||||
const {categoryOptions, pathLabels} = toRefs(state)
|
const { categoryOptions, pathLabels } = toRefs(state)
|
||||||
|
|
||||||
function loadData() {
|
function loadData() {
|
||||||
listCascadeCategories({}).then(response => {
|
listCascadeCategories().then(response => {
|
||||||
state.categoryOptions = response.data
|
state.categoryOptions = response.data
|
||||||
if (props.modelValue.id) {
|
if (goodsInfo.value.id) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
handleCategoryChange()
|
handleCategoryChange()
|
||||||
})
|
})
|
||||||
@@ -63,15 +66,15 @@ const categoryRef = ref(ElCascaderPanel)
|
|||||||
function handleCategoryChange() {
|
function handleCategoryChange() {
|
||||||
const checkNode = categoryRef.value.getCheckedNodes()[0]
|
const checkNode = categoryRef.value.getCheckedNodes()[0]
|
||||||
state.pathLabels = checkNode.pathLabels // 商品分类选择层级提示
|
state.pathLabels = checkNode.pathLabels // 商品分类选择层级提示
|
||||||
props.modelValue.categoryId = checkNode.value
|
goodsInfo.value.categoryId = checkNode.value
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNext() {
|
function handleNext() {
|
||||||
if (!props.modelValue.categoryId) {
|
if (!goodsInfo.value.categoryId) {
|
||||||
ElMessage.warning('请选择商品分类')
|
ElMessage.warning('请选择商品分类')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
emit('next' )
|
emit('next')
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -81,7 +84,6 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.component-container {
|
.component-container {
|
||||||
&__main {
|
&__main {
|
||||||
margin: 20px auto
|
margin: 20px auto
|
||||||
|
|||||||
@@ -1,74 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="component-container">
|
<div class="component-container">
|
||||||
<div class="component-container__main">
|
<div class="component-container__main">
|
||||||
<el-form
|
<el-form ref="dataFormRef" :rules="rules" :model="goodsInfo" label-width="120px">
|
||||||
ref="dataFormRef"
|
|
||||||
:rules="rules"
|
|
||||||
:model="modelValue"
|
|
||||||
label-width="120px"
|
|
||||||
>
|
|
||||||
<el-form-item label="商品品牌" prop="brandId">
|
<el-form-item label="商品品牌" prop="brandId">
|
||||||
<el-select
|
<el-select v-model="goodsInfo.brandId" style="width: 400px" clearable>
|
||||||
v-model="modelValue.brandId"
|
<el-option v-for="item in brandOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
style="width: 400px"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in brandOptions"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="商品名称" prop="name">
|
<el-form-item label="商品名称" prop="name">
|
||||||
<el-input style="width: 400px" v-model="modelValue.name" />
|
<el-input style="width: 400px" v-model="goodsInfo.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="原价" prop="originPrice">
|
<el-form-item label="原价" prop="originPrice">
|
||||||
<el-input style="width: 400px" v-model="modelValue.originPrice" />
|
<el-input style="width: 400px" v-model="goodsInfo.originPrice" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="现价" prop="price">
|
<el-form-item label="现价" prop="price">
|
||||||
<el-input style="width: 400px" v-model="modelValue.price" />
|
<el-input style="width: 400px" v-model="goodsInfo.price" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="商品简介">
|
<el-form-item label="商品简介">
|
||||||
<el-input
|
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 6 }" v-model="goodsInfo.description" />
|
||||||
type="textarea"
|
|
||||||
:autosize="{ minRows: 3, maxRows: 6 }"
|
|
||||||
v-model="modelValue.description"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="商品相册">
|
<el-form-item label="商品相册">
|
||||||
<el-card
|
<el-card v-for="(item, index) in pictures" :key="index"
|
||||||
v-for="(item, index) in pictures"
|
|
||||||
:key="index"
|
|
||||||
style="width: 170px; display: inline-block; margin-left: 10px;text-align:center"
|
style="width: 170px; display: inline-block; margin-left: 10px;text-align:center"
|
||||||
:body-style="{ padding: '10px' }"
|
:body-style="{ padding: '10px' }">
|
||||||
>
|
|
||||||
<single-upload v-model="item.url" :show-close="true" />
|
<single-upload v-model="item.url" :show-close="true" />
|
||||||
|
|
||||||
<div v-if="item.url">
|
<div v-if="item.url">
|
||||||
<el-button
|
<el-button type="text" class="button" v-if="item.main == true" style="color: #ff4d51">商品主图</el-button>
|
||||||
type="text"
|
<el-button type="text" class="button" v-else @click="changeMainPicture(index)">设为主图</el-button>
|
||||||
class="button"
|
|
||||||
v-if="item.main == true"
|
|
||||||
style="color: #ff4d51"
|
|
||||||
>商品主图</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="text"
|
|
||||||
class="button"
|
|
||||||
v-else
|
|
||||||
@click="changeMainPicture(index)"
|
|
||||||
>设为主图</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<!-- 占位 -->
|
<!-- 占位 -->
|
||||||
<el-button type="text" />
|
<el-button type="text" />
|
||||||
</div>
|
</div>
|
||||||
@@ -76,21 +43,19 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="商品详情" prop="detail">
|
<el-form-item label="商品详情" prop="detail">
|
||||||
<editor v-model="modelValue.detail" style="height: 600px" />
|
<editor v-model="goodsInfo.detail" style="height: 600px" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="component-container__footer">
|
<div class="component-container__footer">
|
||||||
<el-button @click="handlePrev">上一步,选择商品分类</el-button>
|
<el-button @click="handlePrev">上一步,选择商品分类</el-button>
|
||||||
<el-button type="primary" @click="handleNext"
|
<el-button type="primary" @click="handleNext">下一步,设置商品属性</el-button>
|
||||||
>下一步,设置商品属性</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
import { computed, onMounted, reactive, ref, toRefs } from "vue";
|
||||||
import { ElForm } from "element-plus";
|
import { ElForm } from "element-plus";
|
||||||
|
|
||||||
// API 依赖
|
// API 依赖
|
||||||
@@ -100,16 +65,23 @@ import { listBrands } from "@/api/pms/brand";
|
|||||||
import Editor from "@/components/WangEditor/index.vue";
|
import Editor from "@/components/WangEditor/index.vue";
|
||||||
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
||||||
|
|
||||||
const emit = defineEmits(["prev", "next"]);
|
const emit = defineEmits(["prev", "next", "update:modelValue"]);
|
||||||
const dataFormRef = ref(ElForm);
|
const dataFormRef = ref(ElForm);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: () => { }
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const goodsInfo: any = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value) => {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
brandOptions: [] as Array<any>,
|
brandOptions: [] as Array<any>,
|
||||||
// 商品图册
|
// 商品图册
|
||||||
@@ -131,17 +103,16 @@ const state = reactive({
|
|||||||
const { brandOptions, pictures, rules } = toRefs(state);
|
const { brandOptions, pictures, rules } = toRefs(state);
|
||||||
|
|
||||||
function loadData() {
|
function loadData() {
|
||||||
listBrands().then(({data}) => {
|
listBrands().then(({ data }) => {
|
||||||
state.brandOptions = data;
|
state.brandOptions = data;
|
||||||
});
|
});
|
||||||
const goodsInfo = props.modelValue;
|
const goodsId = goodsInfo.value.id;
|
||||||
const goodsId = goodsInfo.id;
|
|
||||||
if (goodsId) {
|
if (goodsId) {
|
||||||
const mainPicUrl = goodsInfo.picUrl;
|
const mainPicUrl = goodsInfo.value.picUrl;
|
||||||
if (mainPicUrl) {
|
if (mainPicUrl) {
|
||||||
state.pictures.filter((item) => item.main)[0].url = mainPicUrl;
|
state.pictures.filter((item) => item.main)[0].url = mainPicUrl;
|
||||||
}
|
}
|
||||||
const subPicUrls = goodsInfo.subPicUrls;
|
const subPicUrls = goodsInfo.value.subPicUrls;
|
||||||
if (subPicUrls && subPicUrls.length > 0) {
|
if (subPicUrls && subPicUrls.length > 0) {
|
||||||
for (let i = 1; i <= subPicUrls.length; i++) {
|
for (let i = 1; i <= subPicUrls.length; i++) {
|
||||||
state.pictures[i].url = subPicUrls[i - 1];
|
state.pictures[i].url = subPicUrls[i - 1];
|
||||||
@@ -150,16 +121,6 @@ function loadData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
|
||||||
state.pictures = [
|
|
||||||
{ url: undefined, main: true }, // main 代表主图,可以切换
|
|
||||||
{ url: undefined, main: false },
|
|
||||||
{ url: undefined, main: false },
|
|
||||||
{ url: undefined, main: false },
|
|
||||||
{ url: undefined, main: false },
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 切换主图
|
* 切换主图
|
||||||
*/
|
*/
|
||||||
@@ -185,13 +146,13 @@ function handleNext() {
|
|||||||
.filter((item) => item.main == true && item.url)
|
.filter((item) => item.main == true && item.url)
|
||||||
.map((item) => item.url);
|
.map((item) => item.url);
|
||||||
if (mainPicUrl && mainPicUrl.length > 0) {
|
if (mainPicUrl && mainPicUrl.length > 0) {
|
||||||
props.modelValue.picUrl = mainPicUrl[0];
|
goodsInfo.picUrl = mainPicUrl[0];
|
||||||
}
|
}
|
||||||
const subPicUrl = state.pictures
|
const subPicUrl = state.pictures
|
||||||
.filter((item) => item.main == false && item.url)
|
.filter((item) => item.main == false && item.url)
|
||||||
.map((item) => item.url);
|
.map((item) => item.url);
|
||||||
if (subPicUrl && subPicUrl.length > 0) {
|
if (subPicUrl && subPicUrl.length > 0) {
|
||||||
props.modelValue.subPicUrls = subPicUrl;
|
goodsInfo.subPicUrls = subPicUrl;
|
||||||
}
|
}
|
||||||
emit("next");
|
emit("next");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,29 +4,13 @@
|
|||||||
<el-card class="box-card">
|
<el-card class="box-card">
|
||||||
<template #header>
|
<template #header>
|
||||||
<span>商品规格</span>
|
<span>商品规格</span>
|
||||||
<el-button
|
<el-button :icon="Plus" type="success" @click="handleSpecAdd" size="small" style="float: right">
|
||||||
:icon="Plus"
|
|
||||||
type="success"
|
|
||||||
@click="handleSpecAdd"
|
|
||||||
size="small"
|
|
||||||
style="float: right"
|
|
||||||
>
|
|
||||||
添加规格项
|
添加规格项
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form
|
<el-form ref="specFormRef" :model="specForm" :inline="true" size="small">
|
||||||
ref="specFormRef"
|
<el-table ref="specTableRef" :data="specForm.specList" row-key="id" size="small">
|
||||||
:model="specForm"
|
|
||||||
:inline="true"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<el-table
|
|
||||||
ref="specTableRef"
|
|
||||||
:data="specForm.specList"
|
|
||||||
row-key="id"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
<el-table-column align="center" width="50">
|
<el-table-column align="center" width="50">
|
||||||
<template>
|
<template>
|
||||||
<svg-icon class="drag-handler" icon-class="drag" />
|
<svg-icon class="drag-handler" icon-class="drag" />
|
||||||
@@ -34,66 +18,31 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="规格名" width="200">
|
<el-table-column label="规格名" width="200">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item :prop="'specList[' + scope.$index + '].name'" :rules="rules.spec.name">
|
||||||
:prop="'specList[' + scope.$index + '].name'"
|
<el-input type="text" v-model="scope.row.name" size="small" @input="handleSpecChange()" />
|
||||||
:rules="rules.spec.name"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
type="text"
|
|
||||||
v-model="scope.row.name"
|
|
||||||
size="small"
|
|
||||||
@input="handleSpecChange()"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column>
|
<el-table-column>
|
||||||
<template #header>
|
<template #header>
|
||||||
规格值
|
规格值
|
||||||
<el-link
|
<el-link type="danger" style="font-size: 12px" :underline="false">(默认第一条规格包含图片)</el-link>
|
||||||
type="danger"
|
|
||||||
style="font-size: 12px"
|
|
||||||
:underline="false"
|
|
||||||
>(默认第一条规格包含图片)</el-link
|
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div
|
<div v-for="item in scope.row.values" :key="item.id" style="margin-right: 15px; display: inline-block">
|
||||||
v-for="item in scope.row.values"
|
<el-tag size="small" closable :type="(colors[scope.$index % colors.length] as any)"
|
||||||
:key="item.id"
|
@close="handleSpecValueRemove(scope.$index, item.id)">
|
||||||
style="margin-right: 15px; display: inline-block"
|
|
||||||
>
|
|
||||||
<el-tag
|
|
||||||
size="small"
|
|
||||||
closable
|
|
||||||
:type="colors[scope.$index % colors.length]"
|
|
||||||
@close="handleSpecValueRemove(scope.$index, item.id)"
|
|
||||||
>
|
|
||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<single-upload
|
<single-upload v-model="item.picUrl" v-if="scope.$index == 0" style="margin-top: 5px" />
|
||||||
v-model="item.picUrl"
|
|
||||||
v-if="scope.$index == 0"
|
|
||||||
style="margin-top: 5px"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-input
|
<el-input v-if="tagInputs.length > 0 && tagInputs[scope.$index].visible"
|
||||||
v-if="tagInputs.length > 0 && tagInputs[scope.$index].visible"
|
v-model="tagInputs[scope.$index].value" @keyup.enter="handleSpecValueInput(scope.$index)"
|
||||||
v-model="tagInputs[scope.$index].value"
|
@blur="handleSpecValueInput(scope.$index)" style="width: 80px; vertical-align: top" size="small" />
|
||||||
@keyup.enter="handleSpecValueInput(scope.$index)"
|
<el-button v-else @click="handleSpecValueAdd(scope.$index)" :icon="Plus" style="vertical-align: top"
|
||||||
@blur="handleSpecValueInput(scope.$index)"
|
size="small">
|
||||||
style="width: 80px; vertical-align: top"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
v-else
|
|
||||||
@click="handleSpecValueAdd(scope.$index)"
|
|
||||||
:icon="Plus"
|
|
||||||
style="vertical-align: top"
|
|
||||||
size="small"
|
|
||||||
>
|
|
||||||
添加规格值
|
添加规格值
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -101,14 +50,8 @@
|
|||||||
|
|
||||||
<el-table-column width="60" label="操作">
|
<el-table-column width="60" label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="danger" :icon="Minus" size="small" circle plain
|
||||||
type="danger"
|
@click.stop="handleSpecRemove(scope.$index)" />
|
||||||
:icon="Minus"
|
|
||||||
size="small"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleSpecRemove(scope.$index)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -120,39 +63,23 @@
|
|||||||
<span>商品库存</span>
|
<span>商品库存</span>
|
||||||
</template>
|
</template>
|
||||||
<el-form ref="skuFormRef" :model="skuForm" size="small" :inline="true">
|
<el-form ref="skuFormRef" :model="skuForm" size="small" :inline="true">
|
||||||
<el-table
|
<el-table :data="skuForm.skuList" :span-method="(objectSpanMethod as any)" highlight-current-row size="small"
|
||||||
:data="skuForm.skuList"
|
border>
|
||||||
:span-method="objectSpanMethod"
|
<el-table-column v-for="(title, index) in specTitles" :key="index" align="center"
|
||||||
highlight-current-row
|
:prop="'specValue' + (index + 1)" :label="title">
|
||||||
size="small"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column
|
|
||||||
v-for="(title, index) in specTitles"
|
|
||||||
:key="index"
|
|
||||||
align="center"
|
|
||||||
:prop="'specValue' + (index + 1)"
|
|
||||||
:label="title"
|
|
||||||
>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="商品编码" align="center">
|
<el-table-column label="商品编码" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item :prop="'skuList[' + scope.$index + '].skuSn'" :rules="rules.sku.skuSn">
|
||||||
:prop="'skuList[' + scope.$index + '].skuSn'"
|
<el-input v-model="scope.row.skuSn" />
|
||||||
:rules="rules.sku.skuSn"
|
|
||||||
>
|
|
||||||
<el-input v-model="scope.row.skuSn"/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="价格" align="center">
|
<el-table-column label="价格" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item :prop="'skuList[' + scope.$index + '].price'" :rules="rules.sku.price">
|
||||||
:prop="'skuList[' + scope.$index + '].price'"
|
|
||||||
:rules="rules.sku.price"
|
|
||||||
>
|
|
||||||
<el-input v-model="scope.row.price" />
|
<el-input v-model="scope.row.price" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -160,10 +87,7 @@
|
|||||||
|
|
||||||
<el-table-column label="库存" align="center">
|
<el-table-column label="库存" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-form-item
|
<el-form-item :prop="'skuList[' + scope.$index + '].stockNum'" :rules="rules.sku.stockNum">
|
||||||
:prop="'skuList[' + scope.$index + '].stockNum'"
|
|
||||||
:rules="rules.sku.stockNum"
|
|
||||||
>
|
|
||||||
<el-input v-model="scope.row.stockNum" />
|
<el-input v-model="scope.row.stockNum" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -179,17 +103,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
getCurrentInstance,
|
|
||||||
nextTick,
|
nextTick,
|
||||||
onMounted,
|
onMounted,
|
||||||
reactive,
|
reactive,
|
||||||
ref,
|
ref,
|
||||||
toRefs,
|
toRefs,
|
||||||
unref,
|
watch
|
||||||
watch,
|
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { Plus, Minus } from "@element-plus/icons-vue";
|
import { Plus, Minus } from "@element-plus/icons-vue";
|
||||||
@@ -204,32 +126,41 @@ import SvgIcon from "@/components/SvgIcon/index.vue";
|
|||||||
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
||||||
// import Sortable from 'sortablejs'
|
// import Sortable from 'sortablejs'
|
||||||
|
|
||||||
const categoryId = computed(() => props.modelValue.categoryId);
|
|
||||||
const emit = defineEmits(["prev", "next"]);
|
|
||||||
|
|
||||||
const proxy = getCurrentInstance();
|
const emit = defineEmits(["prev", "next", 'update:modelValue']);
|
||||||
|
|
||||||
|
/* const proxy = getCurrentInstance(); */
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const specTableRef = ref(ElTable);
|
/* const specTableRef = ref(ElTable); */
|
||||||
const specFormRef = ref(ElForm);
|
const specFormRef = ref(ElForm);
|
||||||
const skuFormRef = ref(ElForm);
|
const skuFormRef = ref(ElForm);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: () => {
|
||||||
},
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const goodsInfo: any = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (value) => {
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
specForm: {
|
specForm: {
|
||||||
specList: [],
|
specList: [] as any[],
|
||||||
},
|
},
|
||||||
skuForm: {
|
skuForm: {
|
||||||
skuList: [],
|
skuList: [] as any[],
|
||||||
},
|
},
|
||||||
// 规格项表格标题
|
// 规格项表格标题
|
||||||
specTitles: [],
|
specTitles: [] as any[],
|
||||||
rules: {
|
rules: {
|
||||||
spec: {
|
spec: {
|
||||||
name: [{ required: true, message: "请输入规格名称", trigger: "blur" }],
|
name: [{ required: true, message: "请输入规格名称", trigger: "blur" }],
|
||||||
@@ -245,56 +176,51 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
colors: ["", "success", "warning", "danger"],
|
colors: ["", "success", "warning", "danger"],
|
||||||
tagInputs: [{ value: undefined, visible: false }], // 规格值标签临时值和显隐控制
|
tagInputs: [{ value: undefined, visible: false }], // 规格值标签临时值和显隐控制
|
||||||
loading: undefined,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { specForm, skuForm, specTitles, rules, colors, tagInputs, loading } =
|
const { specForm, skuForm, specTitles, rules, colors, tagInputs } =
|
||||||
toRefs(state);
|
toRefs(state);
|
||||||
|
|
||||||
watch(
|
watch(() => goodsInfo.value.categoryId, (newVal) => {
|
||||||
categoryId,
|
// 商品编辑不加载分类下的规格
|
||||||
(value) => {
|
const goodsId = goodsInfo.value.id;
|
||||||
|
if (goodsId) {
|
||||||
// 商品编辑不加载分类下的规格
|
return false;
|
||||||
const spuId = props.modelValue.id;
|
}
|
||||||
if (spuId) {
|
if (newVal) {
|
||||||
return false;
|
// type=1 商品分类下的规格
|
||||||
}
|
listAttributes({ categoryId: newVal, type: 1 }).then((response) => {
|
||||||
if (value) {
|
const specList = response.data;
|
||||||
// type=1 商品分类下的规格
|
if (specList && specList.length > 0) {
|
||||||
listAttributes({ categoryId: value, type: 1 }).then((response) => {
|
specList.forEach((item: any) => {
|
||||||
const specList = response.data;
|
state.specForm.specList.push({
|
||||||
if (specList && specList.length > 0) {
|
name: item.name,
|
||||||
specList.forEach((item) => {
|
values: [],
|
||||||
state.specForm.specList.push({
|
|
||||||
name: item.name,
|
|
||||||
values: [],
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
loadData();
|
});
|
||||||
}
|
loadData();
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
{
|
{
|
||||||
immediate: true,
|
immediate: true,
|
||||||
deep: true,
|
deep: true,
|
||||||
}
|
})
|
||||||
);
|
|
||||||
|
|
||||||
|
watch(state.specForm.specList, () => {
|
||||||
|
|
||||||
watch(state.specForm.specList,(value)=>{
|
|
||||||
generateSkuList()
|
generateSkuList()
|
||||||
})
|
})
|
||||||
|
|
||||||
function loadData() {
|
function loadData() {
|
||||||
props.modelValue.specList.forEach((specItem) => {
|
goodsInfo.value.specList.forEach((specItem: any) => {
|
||||||
const specIndex = state.specForm.specList.findIndex(
|
const specIndex = state.specForm.specList.findIndex(
|
||||||
(item) => item.name == specItem.name
|
(item: any) => item.name == specItem.name
|
||||||
);
|
);
|
||||||
if (specIndex > -1) {
|
if (specIndex > -1) {
|
||||||
state.specForm.specList[specIndex].values.push({
|
(state.specForm.specList[specIndex] as any).values.push({
|
||||||
id: specItem.id,
|
id: specItem.id,
|
||||||
value: specItem.value,
|
value: specItem.value,
|
||||||
picUrl: specItem.picUrl,
|
picUrl: specItem.picUrl,
|
||||||
@@ -315,7 +241,7 @@ function loadData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SKU规格ID拼接字符串处理
|
// SKU规格ID拼接字符串处理
|
||||||
props.modelValue.skuList.forEach((sku) => {
|
goodsInfo.value.skuList.forEach((sku: any) => {
|
||||||
sku.specIdArr = sku.specIds.split("_");
|
sku.specIdArr = sku.specIds.split("_");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -335,7 +261,7 @@ function loadData() {
|
|||||||
*/
|
*/
|
||||||
function handleSpecChange() {
|
function handleSpecChange() {
|
||||||
const specList = JSON.parse(JSON.stringify(state.specForm.specList));
|
const specList = JSON.parse(JSON.stringify(state.specForm.specList));
|
||||||
state.specTitles = specList.map((item) => item.name);
|
state.specTitles = specList.map((item: any) => item.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -380,23 +306,23 @@ function handleSpecReorder() {
|
|||||||
*/
|
*/
|
||||||
function generateSkuList() {
|
function generateSkuList() {
|
||||||
// 如果规格为空,生成SKU列表为空
|
// 如果规格为空,生成SKU列表为空
|
||||||
if(state.specForm.specList.length==0){
|
if (state.specForm.specList.length == 0) {
|
||||||
state.skuForm.skuList = [];
|
state.skuForm.skuList = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const specList = JSON.parse(
|
const specList = JSON.parse(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
state.specForm.specList.filter((item) => item.values&&item.values.length > 0)
|
state.specForm.specList.filter((item) => item.values && item.values.length > 0)
|
||||||
)
|
)
|
||||||
); // 深拷贝,取有属性的规格项,否则笛卡尔积运算得到的SKU列表值为空
|
); // 深拷贝,取有属性的规格项,否则笛卡尔积运算得到的SKU列表值为空
|
||||||
|
|
||||||
const skuList = specList.reduce(
|
const skuList = specList.reduce(
|
||||||
(acc, curr) => {
|
(acc: any, curr: any) => {
|
||||||
let result = [];
|
let result = [] as any[];
|
||||||
acc.forEach((item) => {
|
acc.forEach((item: any) => {
|
||||||
// curr => { 'id':1,'name':'颜色','values':[{id:1,value:'白色'},{id:2,value:'黑色'},{id:3,value:'蓝色'}] }
|
// curr => { 'id':1,'name':'颜色','values':[{id:1,value:'白色'},{id:2,value:'黑色'},{id:3,value:'蓝色'}] }
|
||||||
curr.values.forEach((v) => {
|
curr.values.forEach((v: any) => {
|
||||||
// v=>{id:1,value:'白色'}
|
// v=>{id:1,value:'白色'}
|
||||||
let temp = Object.assign({}, item);
|
let temp = Object.assign({}, item);
|
||||||
temp.specValues += v.value + "_"; // 规格值拼接
|
temp.specValues += v.value + "_"; // 规格值拼接
|
||||||
@@ -409,17 +335,17 @@ function generateSkuList() {
|
|||||||
[{ specValues: "", specIds: "" }]
|
[{ specValues: "", specIds: "" }]
|
||||||
);
|
);
|
||||||
|
|
||||||
skuList.forEach((item) => {
|
skuList.forEach((item: any) => {
|
||||||
item.specIds = item.specIds.substring(0, item.specIds.length - 1);
|
item.specIds = item.specIds.substring(0, item.specIds.length - 1);
|
||||||
item.name = item.specValues
|
item.name = item.specValues
|
||||||
.substring(0, item.specValues.length - 1)
|
.substring(0, item.specValues.length - 1)
|
||||||
.replaceAll("_", " ");
|
.replaceAll("_", " ");
|
||||||
const specIdArr = item.specIds.split("|");
|
const specIdArr = item.specIds.split("|");
|
||||||
const skus = props.modelValue.skuList.filter(
|
const skus = goodsInfo.value.skuList.filter(
|
||||||
(sku) =>
|
(sku: any) =>
|
||||||
sku.specIdArr.length === specIdArr.length &&
|
sku.specIdArr.length === specIdArr.length &&
|
||||||
sku.specIdArr.every((a) => specIdArr.some((b) => a === b)) &&
|
sku.specIdArr.every((a: any) => specIdArr.some((b: any) => a === b)) &&
|
||||||
specIdArr.every((x) => sku.specIdArr.some((y) => x === y))
|
specIdArr.every((x: any) => sku.specIdArr.some((y: any) => x === y))
|
||||||
); // 数据库的SKU列表
|
); // 数据库的SKU列表
|
||||||
|
|
||||||
if (skus && skus.length > 0) {
|
if (skus && skus.length > 0) {
|
||||||
@@ -432,12 +358,12 @@ function generateSkuList() {
|
|||||||
const specValueArr = item.specValues
|
const specValueArr = item.specValues
|
||||||
.substring(0, item.specValues.length - 1)
|
.substring(0, item.specValues.length - 1)
|
||||||
.split("_"); // ['黑','6+128G','官方标配']
|
.split("_"); // ['黑','6+128G','官方标配']
|
||||||
specValueArr.forEach((v, i) => {
|
specValueArr.forEach((v: any, i: any) => {
|
||||||
const key = "specValue" + (i + 1);
|
const key = "specValue" + (i + 1);
|
||||||
item[key] = v;
|
item[key] = v;
|
||||||
if (i == 0 && state.specForm.specList.length > 0) {
|
if (i == 0 && state.specForm.specList.length > 0) {
|
||||||
const valueIndex = state.specForm.specList[0].values.findIndex(
|
const valueIndex = state.specForm.specList[0].values.findIndex(
|
||||||
(specValue) => specValue.value == v
|
(specValue: any) => specValue.value == v
|
||||||
);
|
);
|
||||||
if (valueIndex > -1) {
|
if (valueIndex > -1) {
|
||||||
item.picUrl = state.specForm.specList[0].values[valueIndex].picUrl;
|
item.picUrl = state.specForm.specList[0].values[valueIndex].picUrl;
|
||||||
@@ -456,7 +382,7 @@ function handleSpecAdd() {
|
|||||||
ElMessage.warning("最多支持3组规格");
|
ElMessage.warning("最多支持3组规格");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.specForm.specList.push({values:[]});
|
state.specForm.specList.push({ values: [] });
|
||||||
state.tagInputs.push({ value: undefined, visible: false });
|
state.tagInputs.push({ value: undefined, visible: false });
|
||||||
handleSpecReorder();
|
handleSpecReorder();
|
||||||
}
|
}
|
||||||
@@ -465,7 +391,7 @@ function handleSpecAdd() {
|
|||||||
* 删除规格
|
* 删除规格
|
||||||
* @param index
|
* @param index
|
||||||
*/
|
*/
|
||||||
function handleSpecRemove(index) {
|
function handleSpecRemove(index: any) {
|
||||||
state.specForm.specList.splice(index, 1);
|
state.specForm.specList.splice(index, 1);
|
||||||
state.tagInputs.splice(index, 1);
|
state.tagInputs.splice(index, 1);
|
||||||
generateSkuList();
|
generateSkuList();
|
||||||
@@ -478,7 +404,7 @@ function handleSpecRemove(index) {
|
|||||||
*
|
*
|
||||||
* @param specIndex
|
* @param specIndex
|
||||||
*/
|
*/
|
||||||
function handleSpecValueAdd(specIndex) {
|
function handleSpecValueAdd(specIndex: any) {
|
||||||
state.tagInputs[specIndex].visible = true;
|
state.tagInputs[specIndex].visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,10 +414,10 @@ function handleSpecValueAdd(specIndex) {
|
|||||||
* @param rowIndex
|
* @param rowIndex
|
||||||
* @param specValueId
|
* @param specValueId
|
||||||
*/
|
*/
|
||||||
function handleSpecValueRemove(rowIndex, specValueId) {
|
function handleSpecValueRemove(rowIndex: any, specValueId: any) {
|
||||||
const specList = JSON.parse(JSON.stringify(state.specForm.specList));
|
const specList = JSON.parse(JSON.stringify(state.specForm.specList));
|
||||||
const removeIndex = specList[rowIndex].values
|
const removeIndex = specList[rowIndex].values
|
||||||
.map((item) => item.id)
|
.map((item: any) => item.id)
|
||||||
.indexOf(specValueId);
|
.indexOf(specValueId);
|
||||||
specList[rowIndex].values.splice(removeIndex, 1);
|
specList[rowIndex].values.splice(removeIndex, 1);
|
||||||
state.specForm.specList = specList;
|
state.specForm.specList = specList;
|
||||||
@@ -503,13 +429,13 @@ function handleSpecValueRemove(rowIndex, specValueId) {
|
|||||||
/**
|
/**
|
||||||
* 规格值输入
|
* 规格值输入
|
||||||
*/
|
*/
|
||||||
function handleSpecValueInput(rowIndex) {
|
function handleSpecValueInput(rowIndex: any) {
|
||||||
const currSpecValue = state.tagInputs[rowIndex].value;
|
const currSpecValue = state.tagInputs[rowIndex].value;
|
||||||
const specValues = state.specForm.specList[rowIndex].values;
|
const specValues = state.specForm.specList[rowIndex].values;
|
||||||
if (
|
if (
|
||||||
specValues &&
|
specValues &&
|
||||||
specValues.length > 0 &&
|
specValues.length > 0 &&
|
||||||
specValues.map((item) => item.value).includes(currSpecValue)
|
specValues.map((item: any) => item.value).includes(currSpecValue)
|
||||||
) {
|
) {
|
||||||
ElMessage.warning("规格值重复,请重新输入");
|
ElMessage.warning("规格值重复,请重新输入");
|
||||||
return false;
|
return false;
|
||||||
@@ -518,12 +444,11 @@ function handleSpecValueInput(rowIndex) {
|
|||||||
if (specValues && specValues.length > 0) {
|
if (specValues && specValues.length > 0) {
|
||||||
// 临时规格值ID tid_1_1
|
// 临时规格值ID tid_1_1
|
||||||
let maxSpecValueIndex = specValues
|
let maxSpecValueIndex = specValues
|
||||||
.filter((item) => item.id.includes("tid_"))
|
.filter((item: any) => item.id.includes("tid_"))
|
||||||
.map((item) => item.id.split("_")[2])
|
.map((item: any) => item.id.split("_")[2])
|
||||||
.reduce((acc, curr) => {
|
.reduce((acc: any, curr: any) => {
|
||||||
return acc > curr ? acc : curr;
|
return acc > curr ? acc : curr;
|
||||||
}, 0);
|
}, 0);
|
||||||
console.log("maxSpecValueIndex", maxSpecValueIndex);
|
|
||||||
state.specForm.specList[rowIndex].values[specValues.length] = {
|
state.specForm.specList[rowIndex].values[specValues.length] = {
|
||||||
value: currSpecValue,
|
value: currSpecValue,
|
||||||
id: "tid_" + (rowIndex + 1) + "_" + ++maxSpecValueIndex,
|
id: "tid_" + (rowIndex + 1) + "_" + ++maxSpecValueIndex,
|
||||||
@@ -545,7 +470,7 @@ function handleSpecValueInput(rowIndex) {
|
|||||||
* @param cellObj 单元格对象
|
* @param cellObj 单元格对象
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
const objectSpanMethod = ({ rowIndex, columnIndex }: any) => {
|
||||||
let mergeRows = [1, 1, 1]; // 分别对应规格1、规格2、规格3列合并的行数
|
let mergeRows = [1, 1, 1]; // 分别对应规格1、规格2、规格3列合并的行数
|
||||||
const specLen = state.specForm.specList.filter(
|
const specLen = state.specForm.specList.filter(
|
||||||
(item) => item.values && item.values.length > 0
|
(item) => item.values && item.values.length > 0
|
||||||
@@ -589,20 +514,18 @@ function submitForm() {
|
|||||||
ElMessage.warning("未添加商品库存");
|
ElMessage.warning("未添加商品库存");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
specFormRef.value.validate((specValid) => {
|
specFormRef.value.validate((specValid: any) => {
|
||||||
if (specValid) {
|
if (specValid) {
|
||||||
skuFormRef.value.validate((skuValid) => {
|
skuFormRef.value.validate((skuValid: any) => {
|
||||||
if (skuValid) {
|
if (skuValid) {
|
||||||
// openFullScreen()
|
|
||||||
|
|
||||||
// 重组商品的规格和SKU列表
|
// 重组商品的规格和SKU列表
|
||||||
let submitsData = Object.assign({}, props.modelValue);
|
let submitsData = Object.assign({}, goodsInfo.value);
|
||||||
delete submitsData.specList;
|
delete submitsData.specList;
|
||||||
delete submitsData.skuList;
|
delete submitsData.skuList;
|
||||||
|
|
||||||
let specList = [];
|
let specList = [] as any[];
|
||||||
state.specForm.specList.forEach((item) => {
|
state.specForm.specList.forEach((item) => {
|
||||||
item.values.forEach((value) => {
|
item.values.forEach((value: any) => {
|
||||||
value.name = item.name;
|
value.name = item.name;
|
||||||
});
|
});
|
||||||
specList = specList.concat(item.values);
|
specList = specList.concat(item.values);
|
||||||
@@ -613,43 +536,35 @@ function submitForm() {
|
|||||||
submitsData.originPrice *= 100;
|
submitsData.originPrice *= 100;
|
||||||
|
|
||||||
let skuList = JSON.parse(JSON.stringify(state.skuForm.skuList));
|
let skuList = JSON.parse(JSON.stringify(state.skuForm.skuList));
|
||||||
skuList.map((item) => {
|
skuList.map((item: any) => {
|
||||||
item.price *= 100;
|
item.price *= 100;
|
||||||
return item;
|
return item;
|
||||||
});
|
});
|
||||||
submitsData.skuList = skuList;
|
submitsData.skuList = skuList;
|
||||||
console.log("提交数据", submitsData);
|
console.log("提交数据", submitsData);
|
||||||
const goodsId = props.modelValue.id;
|
const goodsId = goodsInfo.value.id;
|
||||||
if (goodsId) {
|
if (goodsId) {
|
||||||
// 编辑商品提交
|
// 编辑商品提交
|
||||||
updateGoods(goodsId, submitsData).then(
|
updateGoods(goodsId, submitsData).then(
|
||||||
(res) => {
|
() => {
|
||||||
router.push({ path: "/pms/goods" });
|
router.push({ path: "/pms/goods" });
|
||||||
ElNotification({
|
ElNotification({
|
||||||
title: "提示",
|
title: "提示",
|
||||||
message: "编辑商品成功",
|
message: "编辑商品成功",
|
||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
//closeFullScreen()
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
//closeFullScreen()
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// 新增商品提交
|
// 新增商品提交
|
||||||
addGoods(submitsData).then(
|
addGoods(submitsData).then(
|
||||||
(response) => {
|
() => {
|
||||||
router.push({ path: "/pms/goods" });
|
router.push({ path: "/pms/goods" });
|
||||||
ElNotification({
|
ElNotification({
|
||||||
title: "提示",
|
title: "提示",
|
||||||
message: "新增商品成功",
|
message: "新增商品成功",
|
||||||
type: "success",
|
type: "success",
|
||||||
});
|
});
|
||||||
// closeFullScreen()
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
// closeFullScreen()
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -659,8 +574,8 @@ function submitForm() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function openFullScreen() {
|
/* function openFullScreen() {
|
||||||
state.loading = proxy.$loading({
|
state.loading = (proxy as any).$loading({
|
||||||
lock: true,
|
lock: true,
|
||||||
text: "商品信息提交中,请等待...",
|
text: "商品信息提交中,请等待...",
|
||||||
spinner: "el-icon-loading",
|
spinner: "el-icon-loading",
|
||||||
@@ -670,18 +585,14 @@ function openFullScreen() {
|
|||||||
|
|
||||||
function closeFullScreen() {
|
function closeFullScreen() {
|
||||||
if (state.loading) {
|
if (state.loading) {
|
||||||
state.loading.close();
|
(state.loading as any).close();
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
function handlePrev() {
|
function handlePrev() {
|
||||||
emit("prev");
|
emit("prev");
|
||||||
}
|
}
|
||||||
|
|
||||||
function handNext() {
|
|
||||||
emit("next");
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadData();
|
loadData();
|
||||||
});
|
});
|
||||||
@@ -704,7 +615,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form--inline .el-form-item{
|
.el-form--inline .el-form-item {
|
||||||
margin-top: 18px;
|
margin-top: 18px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,108 +1,77 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-steps :active="active" process-status="finish" finish-status="success" simple>
|
<el-steps :active="active" process-status="finish" finish-status="success" simple>
|
||||||
<el-step title="选择商品分类"/>
|
<el-step title="选择商品分类" />
|
||||||
<el-step title="填写商品信息"/>
|
<el-step title="填写商品信息" />
|
||||||
<el-step title="设置商品属性"/>
|
<el-step title="设置商品属性" />
|
||||||
<el-step title="设置商品库存"/>
|
<el-step title="设置商品库存" />
|
||||||
</el-steps>
|
</el-steps>
|
||||||
|
|
||||||
<goods-category
|
<GoodsCategory v-show="active == 0" v-model="goodsInfo" v-if="loaded == true" @prev="prev" @next="next" />
|
||||||
v-show="active==0"
|
<GoodsInfo v-show="active == 1" v-model="goodsInfo" v-if="loaded == true" @prev="prev" @next="next" />
|
||||||
v-model="goods"
|
<GoodsAttribute v-show="active == 2" v-model="goodsInfo" v-if="loaded == true" @prev="prev" @next="next" />
|
||||||
v-if="loaded==true"
|
<GoodsStock v-show="active == 3" v-model="goodsInfo" v-if="loaded == true" @prev="prev" @next="next" />
|
||||||
@prev="prev"
|
|
||||||
@next="next"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<goods-info
|
|
||||||
v-show="active==1"
|
|
||||||
v-model="goods"
|
|
||||||
v-if="loaded==true"
|
|
||||||
@prev="prev"
|
|
||||||
@next="next"
|
|
||||||
/>
|
|
||||||
<goods-attribute
|
|
||||||
v-show="active==2"
|
|
||||||
v-model="goods"
|
|
||||||
v-if="loaded==true"
|
|
||||||
@prev="prev"
|
|
||||||
@next="next"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<goods-stock
|
|
||||||
v-show="active==3"
|
|
||||||
v-model="goods"
|
|
||||||
v-if="loaded==true"
|
|
||||||
@prev="prev"
|
|
||||||
@next="next"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, toRefs } from "vue";
|
||||||
|
|
||||||
import GoodsCategory from "./components/GoodsCategory.vue";
|
import GoodsCategory from "./components/GoodsCategory.vue";
|
||||||
import GoodsInfo from "./components/GoodsInfo.vue";
|
import GoodsInfo from "./components/GoodsInfo.vue";
|
||||||
import GoodsAttribute from "./components/GoodsAttribute.vue";
|
import GoodsAttribute from "./components/GoodsAttribute.vue";
|
||||||
import GoodsStock from "./components/GoodsStock.vue";
|
import GoodsStock from "./components/GoodsStock.vue";
|
||||||
|
|
||||||
import {getGoodsFormDetail} from "@/api/pms/goods";
|
import { getGoodsDetail } from "@/api/pms/goods";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
import { GoodsDetail } from "@/types";
|
||||||
|
|
||||||
export default {
|
const route = useRoute();
|
||||||
name: "goods-detail",
|
const props = defineProps({
|
||||||
components: {GoodsStock, GoodsCategory, GoodsInfo, GoodsAttribute},
|
goodsId: {
|
||||||
props: ['goodsId'],
|
type: String,
|
||||||
data() {
|
default: () => ''
|
||||||
return {
|
}
|
||||||
loaded: false,
|
})
|
||||||
active: 0,
|
|
||||||
goods: {
|
const state = reactive({
|
||||||
id: undefined,
|
loaded: false,
|
||||||
name: undefined,
|
active: 0,
|
||||||
categoryId: undefined,
|
goodsInfo: {} as GoodsDetail
|
||||||
brandId: undefined,
|
});
|
||||||
originPrice: undefined,
|
|
||||||
price: undefined,
|
const { loaded, active, goodsInfo } = toRefs(state)
|
||||||
picUrl: undefined,
|
|
||||||
album: undefined,
|
function loadData() {
|
||||||
description: undefined,
|
const goodsId = route.query.goodsId as string
|
||||||
detail: undefined,
|
|
||||||
attrList: [],
|
if (goodsId) {
|
||||||
specList: [],
|
getGoodsDetail(goodsId).then((response) => {
|
||||||
skuList: []
|
state.goodsInfo = response.data
|
||||||
}
|
state.goodsInfo.originPrice = state.goodsInfo.originPrice / 100
|
||||||
};
|
state.goodsInfo.price = state.goodsInfo.price / 100
|
||||||
},
|
state.loaded = true
|
||||||
created() {
|
})
|
||||||
this.loadData()
|
} else {
|
||||||
},
|
state.loaded = true
|
||||||
methods: {
|
|
||||||
loadData() {
|
|
||||||
const goodsId = this.$route.query.goodsId
|
|
||||||
console.log('goodsId',goodsId)
|
|
||||||
if (goodsId) {
|
|
||||||
getGoodsFormDetail(goodsId).then(response => {
|
|
||||||
this.goods = response.data
|
|
||||||
this.goods.originPrice = this.goods.originPrice / 100
|
|
||||||
this.goods.price = this.goods.price / 100
|
|
||||||
this.loaded = true
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.loaded = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
prev() {
|
|
||||||
if (this.active-- <= 0) {
|
|
||||||
this.active = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
next() {
|
|
||||||
if (this.active++ >= 3) {
|
|
||||||
this.active = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function prev() {
|
||||||
|
if (state.active-- <= 0) {
|
||||||
|
state.active = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function next() {
|
||||||
|
if (state.active++ >= 3) {
|
||||||
|
state.active = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadData();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<el-cascader
|
<el-cascader
|
||||||
v-model="queryParams.categoryId"
|
v-model="queryParams.categoryId"
|
||||||
placeholder="商品分类"
|
placeholder="商品分类"
|
||||||
:props="{ emitPath: false, expandTrigger: 'hover' }"
|
:props="{ emitPath: false }"
|
||||||
:options="categoryOptions"
|
:options="categoryOptions"
|
||||||
clearable
|
clearable
|
||||||
style="width: 300px"
|
style="width: 300px"
|
||||||
@@ -177,8 +177,6 @@ const state = reactive({
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
ids,
|
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
queryParams,
|
queryParams,
|
||||||
goodsList,
|
goodsList,
|
||||||
|
|||||||
@@ -3,40 +3,20 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
>新增</el-button
|
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="title">
|
<el-form-item prop="title">
|
||||||
<el-input
|
<el-input v-model="queryParams.title" placeholder="广告标题" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="queryParams.title"
|
|
||||||
placeholder="广告标题"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-table
|
<el-table v-loading="loading" :data="advertList" @selection-change="handleSelectionChange" border>
|
||||||
v-loading="loading"
|
|
||||||
:data="advertList"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" min-width="5" align="center" />
|
<el-table-column type="selection" min-width="5" align="center" />
|
||||||
<el-table-column type="index" label="序号" width="80" align="center" />
|
<el-table-column type="index" label="序号" width="80" align="center" />
|
||||||
<el-table-column prop="title" min-width="100" label="广告标题" />
|
<el-table-column prop="title" min-width="100" label="广告标题" />
|
||||||
@@ -45,10 +25,7 @@
|
|||||||
<el-popover placement="right" :width="400" trigger="hover">
|
<el-popover placement="right" :width="400" trigger="hover">
|
||||||
<img :src="scope.row.picUrl" width="400" height="400" />
|
<img :src="scope.row.picUrl" width="400" height="400" />
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<img
|
<img :src="scope.row.picUrl" style="max-height: 60px; max-width: 60px" />
|
||||||
:src="scope.row.picUrl"
|
|
||||||
style="max-height: 60px; max-width: 60px"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
@@ -64,57 +41,27 @@
|
|||||||
<el-table-column prop="sort" label="排序" width="80" />
|
<el-table-column prop="sort" label="排序" width="80" />
|
||||||
<el-table-column label="操作" align="center" width="150">
|
<el-table-column label="操作" align="center" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||||
type="primary"
|
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleUpdate(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页工具条 -->
|
<!-- 分页工具条 -->
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNum"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表单弹窗 -->
|
<!-- 表单弹窗 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="700px">
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="700px">
|
||||||
<el-form
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="100px"
|
|
||||||
>
|
|
||||||
<el-form-item label="广告标题" prop="title">
|
<el-form-item label="广告标题" prop="title">
|
||||||
<el-input v-model="formData.title" />
|
<el-input v-model="formData.title" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="有效期" prop="beginTime">
|
<el-form-item label="有效期" prop="beginTime">
|
||||||
<el-date-picker
|
<el-date-picker v-model="formData.beginTime" placeholder="开始时间" value-format="YYYY-MM-DD" />
|
||||||
v-model="formData.beginTime"
|
|
||||||
placeholder="开始时间"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
/>
|
|
||||||
~
|
~
|
||||||
<el-date-picker
|
<el-date-picker v-model="formData.endTime" placeholder="结束时间" value-format="YYYY-MM-DD" />
|
||||||
v-model="formData.endTime"
|
|
||||||
placeholder="结束时间"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="广告图片" prop="picUrl">
|
<el-form-item label="广告图片" prop="picUrl">
|
||||||
@@ -152,7 +99,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, toRefs, unref } from "vue";
|
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||||
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
||||||
@@ -194,7 +141,6 @@ const state = reactive({
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
queryParams,
|
queryParams,
|
||||||
advertList,
|
advertList,
|
||||||
@@ -206,7 +152,7 @@ const {
|
|||||||
|
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
listAdvertPages(state.queryParams).then(({data}) => {
|
listAdvertPages(state.queryParams).then(({ data }) => {
|
||||||
state.advertList = data.list;
|
state.advertList = data.list;
|
||||||
state.total = data.total;
|
state.total = data.total;
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@@ -225,7 +171,6 @@ function handleSelectionChange(selection: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
resetForm();
|
|
||||||
state.dialog = {
|
state.dialog = {
|
||||||
title: "添加广告",
|
title: "添加广告",
|
||||||
visible: true,
|
visible: true,
|
||||||
@@ -248,13 +193,13 @@ function submitForm() {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
const avertId = state.formData.id;
|
const avertId = state.formData.id;
|
||||||
if (avertId) {
|
if (avertId) {
|
||||||
updateAdvert(avertId, state.formData).then((response) => {
|
updateAdvert(avertId, state.formData).then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
cancel();
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addAdvert(state.formData).then((response) => {
|
addAdvert(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
cancel();
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
@@ -264,16 +209,9 @@ function submitForm() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function cancel() {
|
||||||
* 重置表单
|
|
||||||
*/
|
|
||||||
function resetForm() {
|
|
||||||
state.formData.id = undefined;
|
state.formData.id = undefined;
|
||||||
dataFormRef.value.resetFields();
|
dataFormRef.value.resetFields();
|
||||||
}
|
|
||||||
|
|
||||||
function cancel() {
|
|
||||||
resetForm();
|
|
||||||
state.dialog.visible = false;
|
state.dialog.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,43 +3,23 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
>新增</el-button
|
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="clientId">
|
<el-form-item prop="clientId">
|
||||||
<el-input
|
<el-input v-model="queryParams.clientId" placeholder="输入客户端ID" clearable style="width: 240px"
|
||||||
v-model="queryParams.clientId"
|
@keyup.enter="handleQuery" />
|
||||||
placeholder="输入客户端ID"
|
|
||||||
clearable
|
|
||||||
style="width: 240px"
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<el-table v-loading="loading" :data="clientList" border @selection-change="handleSelectionChange">
|
||||||
v-loading="loading"
|
|
||||||
:data="clientList"
|
|
||||||
border
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="序号" type="index" width="55" align="center" />
|
<el-table-column label="序号" type="index" width="55" align="center" />
|
||||||
<el-table-column label="客户端ID" prop="clientId" width="200" />
|
<el-table-column label="客户端ID" prop="clientId" width="200" />
|
||||||
@@ -47,69 +27,33 @@
|
|||||||
<el-table-column label="域" width="100" prop="scope" />
|
<el-table-column label="域" width="100" prop="scope" />
|
||||||
<el-table-column label="自动放行" prop="autoapprove" width="100" />
|
<el-table-column label="自动放行" prop="autoapprove" width="100" />
|
||||||
<el-table-column label="授权方式" prop="authorizedGrantTypes" />
|
<el-table-column label="授权方式" prop="authorizedGrantTypes" />
|
||||||
<el-table-column
|
<el-table-column label="认证令牌时效(单位:秒)" width="200" prop="accessTokenValidity" />
|
||||||
label="认证令牌时效(单位:秒)"
|
<el-table-column label="刷新令牌时效(单位:秒)" width="200" prop="refreshTokenValidity" />
|
||||||
width="200"
|
|
||||||
prop="accessTokenValidity"
|
|
||||||
/>
|
|
||||||
<el-table-column
|
|
||||||
label="刷新令牌时效(单位:秒)"
|
|
||||||
width="200"
|
|
||||||
prop="refreshTokenValidity"
|
|
||||||
/>
|
|
||||||
<el-table-column label="操作" align="center" width="120">
|
<el-table-column label="操作" align="center" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||||
type="primary"
|
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleUpdate(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页工具条 -->
|
<!-- 分页工具条 -->
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNum"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表单弹窗 -->
|
<!-- 表单弹窗 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="700px">
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="700px">
|
||||||
<el-form
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="100px"
|
|
||||||
>
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="客户端ID" prop="clientId">
|
<el-form-item label="客户端ID" prop="clientId">
|
||||||
<el-input
|
<el-input v-model="formData.clientId" placeholder="请输入客户端ID" />
|
||||||
v-model="formData.clientId"
|
|
||||||
placeholder="请输入客户端ID"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="客户端密钥" prop="clientSecret">
|
<el-form-item label="客户端密钥" prop="clientSecret">
|
||||||
<el-input
|
<el-input v-model="formData.clientSecret" placeholder="请输入客户端密钥" />
|
||||||
v-model="formData.clientSecret"
|
|
||||||
placeholder="请输入客户端密钥"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -132,11 +76,9 @@
|
|||||||
|
|
||||||
<el-form-item label="授权方式" prop="authorizedGrantTypes">
|
<el-form-item label="授权方式" prop="authorizedGrantTypes">
|
||||||
<el-checkbox-group v-model="checkedAuthorizedGrantTypes">
|
<el-checkbox-group v-model="checkedAuthorizedGrantTypes">
|
||||||
<el-checkbox
|
<el-checkbox v-for="item in authorizedGrantTypesOptions" :key="item.value" :label="item.value">{{
|
||||||
v-for="item in authorizedGrantTypesOptions"
|
item.label
|
||||||
:key="item.value"
|
}}
|
||||||
:label="item.value"
|
|
||||||
>{{ item.label }}
|
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -144,19 +86,13 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="认证令牌时效" prop="accessTokenValidity">
|
<el-form-item label="认证令牌时效" prop="accessTokenValidity">
|
||||||
<el-input
|
<el-input v-model="formData.accessTokenValidity" placeholder="请输入认证令牌时效" />
|
||||||
v-model="formData.accessTokenValidity"
|
|
||||||
placeholder="请输入认证令牌时效"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="刷新令牌时效" prop="refreshTokenValidity">
|
<el-form-item label="刷新令牌时效" prop="refreshTokenValidity">
|
||||||
<el-input
|
<el-input v-model="formData.refreshTokenValidity" placeholder="请输入刷新令牌时效" />
|
||||||
v-model="formData.refreshTokenValidity"
|
|
||||||
placeholder="请输入刷新令牌时效"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -164,29 +100,19 @@
|
|||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="回调地址" prop="webServerRedirectUri">
|
<el-form-item label="回调地址" prop="webServerRedirectUri">
|
||||||
<el-input
|
<el-input v-model="formData.webServerRedirectUri" placeholder="请输入回调地址" />
|
||||||
v-model="formData.webServerRedirectUri"
|
|
||||||
placeholder="请输入回调地址"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="权限" prop="authorities">
|
<el-form-item label="权限" prop="authorities">
|
||||||
<el-input
|
<el-input v-model="formData.authorities" placeholder="请输入权限" />
|
||||||
v-model="formData.authorities"
|
|
||||||
placeholder="请输入权限"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="扩展信息" prop="additionalInformation">
|
<el-form-item label="扩展信息" prop="additionalInformation">
|
||||||
<el-input
|
<el-input v-model="formData.additionalInformation" type="textarea" placeholder="JSON格式" />
|
||||||
v-model="formData.additionalInformation"
|
|
||||||
type="textarea"
|
|
||||||
placeholder="JSON格式"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -250,7 +176,6 @@ const state = reactive({
|
|||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
ids,
|
ids,
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
queryParams,
|
queryParams,
|
||||||
clientList,
|
clientList,
|
||||||
@@ -318,7 +243,7 @@ function submitForm() {
|
|||||||
state.checkedAuthorizedGrantTypes.join(",");
|
state.checkedAuthorizedGrantTypes.join(",");
|
||||||
if (state.dialog.type == "edit") {
|
if (state.dialog.type == "edit") {
|
||||||
updateClient(state.formData.clientId, state.formData).then(
|
updateClient(state.formData.clientId, state.formData).then(
|
||||||
(response) => {
|
() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
state.dialog.visible = false;
|
state.dialog.visible = false;
|
||||||
cancel();
|
cancel();
|
||||||
@@ -326,7 +251,7 @@ function submitForm() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
addClient(state.formData).then((response) => {
|
addClient(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
cancel();
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
|
|||||||
@@ -179,7 +179,6 @@ const state = reactive({
|
|||||||
ids: [] as number[],
|
ids: [] as number[],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
single: true,
|
single: true,
|
||||||
disabled: false,
|
|
||||||
loading: true,
|
loading: true,
|
||||||
// 表格树数据
|
// 表格树数据
|
||||||
deptList: [] as DeptItem[],
|
deptList: [] as DeptItem[],
|
||||||
@@ -205,9 +204,7 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ids,
|
|
||||||
single,
|
single,
|
||||||
disabled,
|
|
||||||
loading,
|
loading,
|
||||||
deptList,
|
deptList,
|
||||||
deptOptions,
|
deptOptions,
|
||||||
@@ -257,14 +254,6 @@ async function loadDeptOptions() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 表单重置
|
|
||||||
**/
|
|
||||||
function resetForm() {
|
|
||||||
state.formData.id = undefined;
|
|
||||||
dataFormRef.value.resetFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加部门
|
* 添加部门
|
||||||
*/
|
*/
|
||||||
@@ -300,15 +289,15 @@ function submitForm() {
|
|||||||
dataForm.validate((valid: any) => {
|
dataForm.validate((valid: any) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateDept(state.formData.id, state.formData).then((res: any) => {
|
updateDept(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addDept(state.formData).then(() => {
|
addDept(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -345,7 +334,8 @@ function handleDelete(row: any) {
|
|||||||
* 取消/关闭弹窗
|
* 取消/关闭弹窗
|
||||||
**/
|
**/
|
||||||
function cancel() {
|
function cancel() {
|
||||||
resetForm();
|
state.formData.id = undefined;
|
||||||
|
dataFormRef.value.resetFields();
|
||||||
state.dialog.visible = false;
|
state.dialog.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,43 +3,23 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="state.queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="state.queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
>新增</el-button
|
<el-button type="danger" :icon="Delete" :disabled="state.multiple" @click="handleDelete">删除
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="state.multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除
|
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
<el-input
|
<el-input v-model="state.queryParams.name" placeholder="字典名称" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="state.queryParams.name"
|
|
||||||
placeholder="字典名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery()">搜索</el-button>
|
||||||
>搜索</el-button
|
<el-button :icon="Refresh" @click="resetQuery()">重置</el-button>
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetForm">重置</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<el-table highlight-current-row :data="dictList" v-loading="loading" @row-click="handleRowClick"
|
||||||
highlight-current-row
|
@selection-change="handleSelectionChange" border>
|
||||||
:data="dictList"
|
|
||||||
v-loading="loading"
|
|
||||||
@row-click="handleRowClick"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="字典名称" prop="name" width="120" />
|
<el-table-column label="字典名称" prop="name" width="120" />
|
||||||
<el-table-column label="字典编码" prop="code" />
|
<el-table-column label="字典编码" prop="code" />
|
||||||
@@ -52,45 +32,18 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" align="center" width="150">
|
<el-table-column label="操作" align="center" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||||
type="primary"
|
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleUpdate(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNum"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 弹窗表单 -->
|
<!-- 弹窗表单 -->
|
||||||
<el-dialog
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" @close="cancel">
|
||||||
:title="dialog.title"
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="80px">
|
||||||
v-model="dialog.visible"
|
|
||||||
width="500px"
|
|
||||||
@close="cancel"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="80px"
|
|
||||||
>
|
|
||||||
<el-form-item label="字典名称" prop="name">
|
<el-form-item label="字典名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入字典名称" />
|
<el-input v-model="formData.name" placeholder="请输入字典名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -104,12 +57,8 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input
|
<el-input v-model="formData.remark" type="textarea" placeholder="请输入内容"
|
||||||
v-model="formData.remark"
|
:autosize="{ minRows: 2, maxRows: 4 }" />
|
||||||
type="textarea"
|
|
||||||
placeholder="请输入内容"
|
|
||||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -123,7 +72,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
import { onMounted, reactive, ref, toRefs, defineEmits } from "vue";
|
||||||
import {
|
import {
|
||||||
listDictPages,
|
listDictPages,
|
||||||
getDictFormDetail,
|
getDictFormDetail,
|
||||||
@@ -134,7 +83,6 @@ import {
|
|||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { Dialog, Dict, DictFormData, DictQueryParam } from "@/types";
|
import { Dialog, Dict, DictFormData, DictQueryParam } from "@/types";
|
||||||
import { status } from "nprogress";
|
|
||||||
|
|
||||||
const queryFormRef = ref(ElForm);
|
const queryFormRef = ref(ElForm);
|
||||||
const dataFormRef = ref(ElForm);
|
const dataFormRef = ref(ElForm);
|
||||||
@@ -155,7 +103,7 @@ const state = reactive({
|
|||||||
} as DictQueryParam,
|
} as DictQueryParam,
|
||||||
dictList: [] as Dict[],
|
dictList: [] as Dict[],
|
||||||
total: 0,
|
total: 0,
|
||||||
dialog: {visible:false} as Dialog,
|
dialog: { visible: false } as Dialog,
|
||||||
formData: {
|
formData: {
|
||||||
status: 1,
|
status: 1,
|
||||||
} as DictFormData,
|
} as DictFormData,
|
||||||
@@ -168,14 +116,11 @@ const state = reactive({
|
|||||||
const {
|
const {
|
||||||
total,
|
total,
|
||||||
dialog,
|
dialog,
|
||||||
ids,
|
|
||||||
loading,
|
loading,
|
||||||
single,
|
|
||||||
multiple,
|
|
||||||
queryParams,
|
|
||||||
dictList,
|
dictList,
|
||||||
formData,
|
formData,
|
||||||
rules,
|
rules,
|
||||||
|
queryParams
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
@@ -221,15 +166,15 @@ function submitForm() {
|
|||||||
dataFormRef.value.validate((isValid: boolean) => {
|
dataFormRef.value.validate((isValid: boolean) => {
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateDict(state.formData.id, state.formData).then((response) => {
|
updateDict(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
state.dialog.visible = false;
|
cancel()
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addDict(state.formData).then((response) => {
|
addDict(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
state.dialog.visible = false;
|
cancel()
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -237,12 +182,9 @@ function submitForm() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
function cancel() {
|
||||||
state.formData.id = undefined;
|
state.formData.id = undefined;
|
||||||
dataFormRef.value.resetFields();
|
dataFormRef.value.resetFields();
|
||||||
}
|
|
||||||
|
|
||||||
function cancel() {
|
|
||||||
state.dialog.visible = false;
|
state.dialog.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,39 +3,20 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
>新增</el-button
|
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
<el-input
|
<el-input v-model="queryParams.name" placeholder="数据项名称" clearable />
|
||||||
v-model="queryParams.name"
|
|
||||||
placeholder="数据项名称"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<el-table :data="dictItemList" v-loading="loading" border @selection-change="handleSelectionChange">
|
||||||
:data="dictItemList"
|
|
||||||
v-loading="loading"
|
|
||||||
border
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" min-width="5%" />
|
<el-table-column type="selection" min-width="5%" />
|
||||||
<el-table-column label="数据项名称" prop="name" />
|
<el-table-column label="数据项名称" prop="name" />
|
||||||
<el-table-column label="数据项值" prop="value" />
|
<el-table-column label="数据项值" prop="value" />
|
||||||
@@ -47,76 +28,37 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||||
type="primary"
|
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleUpdate(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||||
v-show="state.total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="state.total"
|
|
||||||
v-model:page="state.queryParams.pageNum"
|
|
||||||
v-model:limit="state.queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表单弹窗 -->
|
<!-- 表单弹窗 -->
|
||||||
<el-dialog
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" @close="cancel">
|
||||||
:title="dialog.title"
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
v-model="dialog.visible"
|
|
||||||
width="500px"
|
|
||||||
@close="cancel"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="100px"
|
|
||||||
>
|
|
||||||
<el-form-item label="字典名称">
|
<el-form-item label="字典名称">
|
||||||
<el-input v-model="props.dictName" :disabled="true" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字典项名称" prop="name">
|
<el-form-item label="字典项名称" prop="name">
|
||||||
<el-input
|
<el-input v-model="formData.name" placeholder="请输入字典项名称" />
|
||||||
v-model="state.formData.name"
|
|
||||||
placeholder="请输入字典项名称"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字典项值" prop="value">
|
<el-form-item label="字典项值" prop="value">
|
||||||
<el-input
|
<el-input v-model="formData.value" placeholder="请输入字典项值" />
|
||||||
v-model="state.formData.value"
|
|
||||||
placeholder="请输入字典项值"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="排序" prop="sort">
|
<el-form-item label="排序" prop="sort">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.sort" style="width: 80px" controls-position="right" :min="0" />
|
||||||
v-model="state.formData.sort"
|
|
||||||
style="width: 80px"
|
|
||||||
controls-position="right"
|
|
||||||
:min="0"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-radio-group v-model="state.formData.status">
|
<el-radio-group v-model="formData.status">
|
||||||
<el-radio :label="1">正常</el-radio>
|
<el-radio :label="1">正常</el-radio>
|
||||||
<el-radio :label="0">停用</el-radio>
|
<el-radio :label="0">停用</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注" prop="remark">
|
<el-form-item label="备注" prop="remark">
|
||||||
<el-input v-model="state.formData.remark" type="textarea"></el-input>
|
<el-input v-model="formData.remark" type="textarea"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -130,7 +72,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref, toRefs, unref, watch } from "vue";
|
import { onMounted, reactive, ref, toRefs, watch } from "vue";
|
||||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -147,15 +89,18 @@ import {
|
|||||||
} from "@/api/system/dict";
|
} from "@/api/system/dict";
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
dictCode: {
|
dictCode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: () => {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
},
|
},
|
||||||
dictName: {
|
dictName: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: () => {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -179,32 +124,33 @@ const state = reactive({
|
|||||||
single: true,
|
single: true,
|
||||||
// 非多个禁用
|
// 非多个禁用
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
total: 0,
|
||||||
queryParams: { pageNum: 1, pageSize: 10 } as DictItemQueryParam,
|
queryParams: { pageNum: 1, pageSize: 10 } as DictItemQueryParam,
|
||||||
dictItemList: [] as DictItem[],
|
dictItemList: [] as DictItem[],
|
||||||
total: 0,
|
|
||||||
dialog: { visible: false } as Dialog,
|
dialog: { visible: false } as Dialog,
|
||||||
formData: {
|
formData: {
|
||||||
dictCode: props.dictCode,
|
dictCode: props.dictCode,
|
||||||
|
dictName: props.dictName,
|
||||||
status: 1,
|
status: 1,
|
||||||
sort: 1,
|
sort: 1,
|
||||||
} as DictItemFormData,
|
} as DictItemFormData,
|
||||||
rules: {
|
rules: {
|
||||||
name: [{ required: true, message: "请输入字典项名称", trigger: "blur" }],
|
name: [{ required: true, message: "请输入字典项名称", trigger: "blur" }],
|
||||||
value: [{ required: true, message: "请输入字典项值", trigger: "blur" }],
|
value: [{ required: true, message: "请输入字典项值", trigger: "blur" }]
|
||||||
},
|
},
|
||||||
|
localDictCode: props.dictCode,
|
||||||
|
localDictName: props.dictName
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
ids,
|
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
queryParams,
|
queryParams,
|
||||||
dictItemList,
|
dictItemList,
|
||||||
total,
|
|
||||||
dialog,
|
dialog,
|
||||||
formData,
|
formData,
|
||||||
rules,
|
rules,
|
||||||
|
total
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
@@ -260,15 +206,15 @@ function submitForm() {
|
|||||||
dataFormRef.value.validate((isValid: boolean) => {
|
dataFormRef.value.validate((isValid: boolean) => {
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateDictItem(state.formData.id, state.formData).then((response) => {
|
updateDictItem(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addDictItem(state.formData).then((response) => {
|
addDictItem(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -276,13 +222,10 @@ function submitForm() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetForm() {
|
|
||||||
state.formData.id = undefined;
|
|
||||||
dataFormRef.value.resetFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancel() {
|
function cancel() {
|
||||||
state.dialog.visible = false;
|
state.dialog.visible = false;
|
||||||
|
state.formData.id = undefined;
|
||||||
|
dataFormRef.value.resetFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete(row: any) {
|
function handleDelete(row: any) {
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
<template #header>
|
<template #header>
|
||||||
<svg-icon color="#333" icon-class="dict"/>
|
<svg-icon color="#333" icon-class="dict"/>
|
||||||
<span style="margin:0 5px;">字典数据项</span>
|
<span style="margin:0 5px;">字典数据项</span>
|
||||||
<el-tag type="success" v-if=" state.dictCode" size="small">{{ state.dictName }}</el-tag>
|
<el-tag type="success" v-if="dictCode" size="small">{{dictName }}</el-tag>
|
||||||
<el-tag type="warning" v-else size="small">未选择字典</el-tag>
|
<el-tag type="warning" v-else size="small">未选择字典</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<!-- 字典项组件 -->
|
<!-- 字典项组件 -->
|
||||||
<dict-item :dictName="state.dictName" :dictCode='state.dictCode'/>
|
<dict-item :dictName="dictName" :dictCode='dictCode'/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|||||||
@@ -3,43 +3,25 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
>新增</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
<el-input
|
<el-input v-model="queryParams.name" placeholder="菜单名称" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="queryParams.name"
|
|
||||||
placeholder="菜单名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<el-table v-loading="loading" :data="menuList" highlight-current-row
|
||||||
v-loading="loading"
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @row-click="handleRowClick" row-key="id"
|
||||||
:data="menuList"
|
border>
|
||||||
highlight-current-row
|
|
||||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
|
||||||
@row-click="handleRowClick"
|
|
||||||
row-key="id"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column label="菜单名称">
|
<el-table-column label="菜单名称">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<svg-icon
|
<svg-icon color="#333" :icon-class="scope.row.icon ? scope.row.icon : 'build'" />
|
||||||
color="#333"
|
|
||||||
:icon-class="scope.row.icon ? scope.row.icon : 'build'"
|
|
||||||
/>
|
|
||||||
{{ scope.row.name }}
|
{{ scope.row.name }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -53,45 +35,18 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" align="center" width="200">
|
<el-table-column label="操作" align="center" width="200">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="success" :icon="Plus" circle plain @click.stop="handleAdd(scope.row)" />
|
||||||
type="success"
|
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||||
:icon="Plus"
|
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleAdd(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleUpdate(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 弹窗表单 -->
|
<!-- 弹窗表单 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="750px">
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="750px">
|
||||||
<el-form
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="100px"
|
|
||||||
>
|
|
||||||
<el-form-item label="父级菜单" prop="parentId">
|
<el-form-item label="父级菜单" prop="parentId">
|
||||||
<tree-select
|
<tree-select v-model="formData.parentId" :options="menuOptions" placeholder="选择上级菜单" />
|
||||||
v-model="formData.parentId"
|
|
||||||
:options="menuOptions"
|
|
||||||
placeholder="选择上级菜单"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="菜单名称" prop="name">
|
<el-form-item label="菜单名称" prop="name">
|
||||||
@@ -110,51 +65,24 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="!isExternalPath" label="页面路径" prop="component">
|
<el-form-item v-if="!isExternalPath" label="页面路径" prop="component">
|
||||||
<el-input
|
<el-input v-model="formData.component" placeholder="system/user/index" style="width: 95%">
|
||||||
v-model="formData.component"
|
<template v-if="formData.parentId != 0" #prepend>src/views/</template>
|
||||||
placeholder="system/user/index"
|
|
||||||
style="width: 95%"
|
|
||||||
>
|
|
||||||
<template v-if="formData.parentId != 0" #prepend
|
|
||||||
>src/views/</template
|
|
||||||
>
|
|
||||||
<template v-if="formData.parentId != 0" #append>.vue</template>
|
<template v-if="formData.parentId != 0" #append>.vue</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
|
||||||
<el-tooltip
|
<el-tooltip effect="dark" content="请输入组件路径,如果是父组件填写 Layout 即可" placement="right">
|
||||||
effect="dark"
|
<i class="el-icon-info" style="margin-left: 10px; color: darkseagreen"></i>
|
||||||
content="请输入组件路径,如果是父组件填写 Layout 即可"
|
|
||||||
placement="right"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="el-icon-info"
|
|
||||||
style="margin-left: 10px; color: darkseagreen"
|
|
||||||
></i>
|
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="图标" prop="icon">
|
<el-form-item label="图标" prop="icon">
|
||||||
<el-popover
|
<el-popover placement="bottom-start" :width="570" trigger="click" visible="iconSelectVisible">
|
||||||
placement="bottom-start"
|
|
||||||
:width="570"
|
|
||||||
trigger="click"
|
|
||||||
v-model:visible="iconSelectVisible"
|
|
||||||
>
|
|
||||||
<icon-select ref="iconSelectRef" @selected="selected" />
|
<icon-select ref="iconSelectRef" @selected="selected" />
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-input
|
<el-input v-model="formData.icon" placeholder="点击选择图标" readonly @click="iconSelectVisible = true">
|
||||||
v-model="formData.icon"
|
|
||||||
placeholder="点击选择图标"
|
|
||||||
readonly
|
|
||||||
@click="iconSelectVisible = true"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<svg-icon
|
<svg-icon :icon-class="formData.icon ? formData.icon : 'color'" class="el-input__icon"
|
||||||
:icon-class="formData.icon ? formData.icon : 'color'"
|
style="margin: auto" color="#999" />
|
||||||
class="el-input__icon"
|
|
||||||
style="margin: auto"
|
|
||||||
color="#999"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</template>
|
</template>
|
||||||
@@ -169,20 +97,11 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="排序" prop="sort">
|
<el-form-item label="排序" prop="sort">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.sort" style="width: 100px" controls-position="right" :min="0" />
|
||||||
v-model="formData.sort"
|
|
||||||
style="width: 100px"
|
|
||||||
controls-position="right"
|
|
||||||
:min="0"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="跳转路径">
|
<el-form-item label="跳转路径">
|
||||||
<el-input
|
<el-input v-model="formData.redirect" placeholder="请输入跳转路径" maxlength="50" />
|
||||||
v-model="formData.redirect"
|
|
||||||
placeholder="请输入跳转路径"
|
|
||||||
maxlength="50"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
@@ -197,7 +116,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, unref, onMounted, toRefs } from "vue";
|
import { reactive, ref, onMounted, toRefs, defineEmits } from "vue";
|
||||||
|
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||||
@@ -240,8 +159,7 @@ const state = reactive({
|
|||||||
multiple: true,
|
multiple: true,
|
||||||
queryParams: {} as MenuQueryParam,
|
queryParams: {} as MenuQueryParam,
|
||||||
menuList: [] as MenuItem[],
|
menuList: [] as MenuItem[],
|
||||||
total: 0,
|
dialog: { visible: false } as Dialog,
|
||||||
dialog: {visible:false} as Dialog,
|
|
||||||
formData: {
|
formData: {
|
||||||
parentId: 0,
|
parentId: 0,
|
||||||
visible: 1,
|
visible: 1,
|
||||||
@@ -256,16 +174,13 @@ const state = reactive({
|
|||||||
menuOptions: [] as Option[],
|
menuOptions: [] as Option[],
|
||||||
currentRow: undefined,
|
currentRow: undefined,
|
||||||
isExternalPath: false,
|
isExternalPath: false,
|
||||||
iconSelectVisible: false,
|
iconSelectVisible: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
single,
|
|
||||||
multiple,
|
|
||||||
queryParams,
|
queryParams,
|
||||||
menuList,
|
menuList,
|
||||||
total,
|
|
||||||
dialog,
|
dialog,
|
||||||
formData,
|
formData,
|
||||||
rules,
|
rules,
|
||||||
@@ -307,15 +222,7 @@ function resetQuery() {
|
|||||||
handleQuery();
|
handleQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSelectionChange(selection: any) {
|
|
||||||
state.ids = selection.map((item: any) => item.id);
|
|
||||||
state.single = selection.length !== 1;
|
|
||||||
state.multiple = !selection.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRowClick(row: any) {
|
function handleRowClick(row: any) {
|
||||||
|
|
||||||
console.log('handleRowClick',row)
|
|
||||||
state.currentRow = JSON.parse(JSON.stringify(row));
|
state.currentRow = JSON.parse(JSON.stringify(row));
|
||||||
emit("menuClick", row);
|
emit("menuClick", row);
|
||||||
}
|
}
|
||||||
@@ -367,15 +274,15 @@ function submitForm() {
|
|||||||
dataFormRef.value.validate((isValid: boolean) => {
|
dataFormRef.value.validate((isValid: boolean) => {
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateMenu(state.formData.id, state.formData).then((response) => {
|
updateMenu(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addMenu(state.formData).then((response) => {
|
addMenu(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -399,29 +306,18 @@ function handleDelete(row: any) {
|
|||||||
.catch(() => ElMessage.info("已取消删除"));
|
.catch(() => ElMessage.info("已取消删除"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置表单
|
|
||||||
*/
|
|
||||||
function resetForm() {
|
|
||||||
state.formData.id = undefined;
|
|
||||||
dataFormRef.value.resetFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消关闭弹窗
|
* 取消关闭弹窗
|
||||||
*/
|
*/
|
||||||
function cancel() {
|
function cancel() {
|
||||||
|
state.formData.id = undefined;
|
||||||
|
dataFormRef.value.resetFields();
|
||||||
state.dialog.visible = false;
|
state.dialog.visible = false;
|
||||||
resetForm();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示图标选择下拉
|
* 选择图标后事件
|
||||||
*/
|
*/
|
||||||
function showIconSelect() {
|
|
||||||
state.iconSelectVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function selected(name: string) {
|
function selected(name: string) {
|
||||||
state.formData.icon = name;
|
state.formData.icon = name;
|
||||||
state.iconSelectVisible = false;
|
state.iconSelectVisible = false;
|
||||||
|
|||||||
@@ -3,44 +3,20 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button
|
<el-button type="success" :icon="Plus" :disabled="!menuId" @click="handleAdd">新增</el-button>
|
||||||
type="success"
|
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||||
:icon="Plus"
|
|
||||||
:disabled="!menuId"
|
|
||||||
@click="handleAdd"
|
|
||||||
>新增</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
<el-input
|
<el-input v-model="queryParams.name" placeholder="权限名称" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="queryParams.name"
|
|
||||||
placeholder="权限名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<el-table :data="permList" v-loading="loading" @selection-change="handleSelectionChange" border>
|
||||||
:data="permList"
|
|
||||||
v-loading="loading"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="40" align="center" />
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
<el-table-column label="权限名称" prop="name" width="150" />
|
<el-table-column label="权限名称" prop="name" width="150" />
|
||||||
<el-table-column label="URL权限" align="center">
|
<el-table-column label="URL权限" align="center">
|
||||||
@@ -51,41 +27,19 @@
|
|||||||
<el-table-column label="按钮权限" prop="btnPerm" width="200" />
|
<el-table-column label="按钮权限" prop="btnPerm" width="200" />
|
||||||
<el-table-column label="操作" align="center" width="150">
|
<el-table-column label="操作" align="center" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" :icon="Edit" circle plain @click="handleUpdate(scope.row)" />
|
||||||
type="primary"
|
<el-button type="danger" :icon="Delete" circle plain @click="handleDelete(scope.row)" />
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click="handleUpdate(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页工具条 -->
|
<!-- 分页工具条 -->
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" :v-model:page="queryParams.pageNum" :v-model:limit="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="total"
|
|
||||||
:page="queryParams.pageNum"
|
|
||||||
:limit="queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表单弹窗 -->
|
<!-- 表单弹窗 -->
|
||||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="700px">
|
<el-dialog :title="dialog.title" v-model="dialog.visible" width="700px">
|
||||||
<el-form
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="120px">
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="120px"
|
|
||||||
>
|
|
||||||
<el-form-item label="权限名称" prop="name">
|
<el-form-item label="权限名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入权限名称" />
|
<el-input v-model="formData.name" placeholder="请输入权限名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -93,37 +47,21 @@
|
|||||||
<el-form-item label="URL权限标识" prop="urlPerm">
|
<el-form-item label="URL权限标识" prop="urlPerm">
|
||||||
<el-input placeholder="/api/v1/users" v-model="urlPerm.requestPath">
|
<el-input placeholder="/api/v1/users" v-model="urlPerm.requestPath">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<el-select
|
<el-select v-model="urlPerm.serviceName" style="width: 130px" placeholder="所属服务" clearable>
|
||||||
v-model="urlPerm.serviceName"
|
<el-option v-for="item in microServiceOptions" :key="item.value" :value="item.value"
|
||||||
style="width: 130px"
|
:label="item.label" />
|
||||||
placeholder="所属服务"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in microServiceOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:value="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<el-select
|
<el-select v-model="urlPerm.requestMethod" style="width: 120px; margin-left: 20px" placeholder="请求方式"
|
||||||
v-model="urlPerm.requestMethod"
|
clearable>
|
||||||
style="width: 120px; margin-left: 20px"
|
<el-option v-for="item in requestMethodOptions" :key="item.value" :value="item.value"
|
||||||
placeholder="请求方式"
|
:label="item.label" />
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in requestMethodOptions"
|
|
||||||
:key="item.value"
|
|
||||||
:value="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-link v-show="urlPerm.requestMethod">
|
<el-link v-show="urlPerm.requestMethod">
|
||||||
{{ urlPerm.requestMethod }}:/{{ urlPerm.serviceName
|
{{ urlPerm.requestMethod }}:/{{
|
||||||
|
urlPerm.serviceName
|
||||||
}}{{ urlPerm.requestPath }}
|
}}{{ urlPerm.requestPath }}
|
||||||
</el-link>
|
</el-link>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -143,22 +81,25 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
|
||||||
listPermPages,
|
|
||||||
getPermFormDetail,
|
|
||||||
addPerm,
|
|
||||||
updatePerm,
|
|
||||||
deletePerms,
|
|
||||||
} from "@/api/system/perm";
|
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
|
||||||
import {
|
import {
|
||||||
onMounted,
|
onMounted,
|
||||||
watch,
|
watch,
|
||||||
reactive,
|
reactive,
|
||||||
ref,
|
ref,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
toRefs,
|
toRefs
|
||||||
} from "vue";
|
} from "vue";
|
||||||
|
|
||||||
|
import {
|
||||||
|
listPermPages,
|
||||||
|
getPermFormDetail,
|
||||||
|
addPerm,
|
||||||
|
updatePerm,
|
||||||
|
deletePerms
|
||||||
|
} from "@/api/system/perm";
|
||||||
|
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -176,7 +117,9 @@ const dataFormRef = ref(ElForm);
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
menuId: {
|
menuId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: () => {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -216,14 +159,12 @@ const state = reactive({
|
|||||||
urlPerm: {
|
urlPerm: {
|
||||||
requestMethod: "",
|
requestMethod: "",
|
||||||
serviceName: "",
|
serviceName: "",
|
||||||
requestPath: "",
|
requestPath: ""
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
ids,
|
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
permList,
|
permList,
|
||||||
total,
|
total,
|
||||||
@@ -280,7 +221,7 @@ function handleAdd() {
|
|||||||
loadDictOptions();
|
loadDictOptions();
|
||||||
state.dialog = {
|
state.dialog = {
|
||||||
title: "添加权限",
|
title: "添加权限",
|
||||||
visible: true,
|
visible: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,13 +278,13 @@ function submitForm() {
|
|||||||
|
|
||||||
state.formData.menuId = props.menuId;
|
state.formData.menuId = props.menuId;
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updatePerm(state.formData.id, state.formData).then((response) => {
|
updatePerm(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
cancel();
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addPerm(state.formData).then((response) => {
|
addPerm(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
cancel();
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
|
|||||||
@@ -4,44 +4,26 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="16">
|
<el-col :span="16">
|
||||||
<el-button
|
<el-button type="success" plain :icon="Switch" @click="toggleExpandAll">展开/折叠</el-button>
|
||||||
type="success"
|
|
||||||
plain
|
|
||||||
:icon="Switch"
|
|
||||||
@click="toggleExpandAll"
|
|
||||||
>展开/折叠</el-button
|
|
||||||
>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8" style="text-align: right">
|
<el-col :span="8" style="text-align: right">
|
||||||
<el-button type="primary" :icon="Check" @click="handleSubmit"
|
<el-button type="primary" :icon="Check" @click="handleSubmit">提交</el-button>
|
||||||
>提交</el-button
|
|
||||||
>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<el-tree
|
<el-tree ref="menuRef" v-if="refreshTree" :default-expanded-keys="expandedKeys" :default-expand-all="isExpandAll"
|
||||||
ref="menuRef"
|
:data="menuOptions" show-checkbox node-key="id" empty-text="加载菜单中..." :check-strictly="checkStrictly"
|
||||||
v-if="refreshTree"
|
highlight-current @node-click="handleNodeClick" />
|
||||||
:default-expanded-keys="expandedKeys"
|
|
||||||
:default-expand-all="isExpandAll"
|
|
||||||
:data="menuOptions"
|
|
||||||
show-checkbox
|
|
||||||
node-key="id"
|
|
||||||
empty-text="加载菜单中..."
|
|
||||||
:check-strictly="checkStrictly"
|
|
||||||
highlight-current
|
|
||||||
@node-click="handleNodeClick"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { nextTick, onMounted, reactive, ref, toRefs, watch } from "vue";
|
||||||
import { listSelectMenus } from "@/api/system/menu";
|
import { listSelectMenus } from "@/api/system/menu";
|
||||||
import { listRoleMenuIds, updateRoleMenu } from "@/api/system/role";
|
import { listRoleMenuIds, updateRoleMenu } from "@/api/system/role";
|
||||||
import { nextTick, onMounted, reactive, ref, toRefs, watch } from "vue";
|
import { ElTree, ElMessage } from "element-plus";
|
||||||
import { ElTree, ElMessage, ElMessageBox } from "element-plus";
|
|
||||||
import { Switch, Check } from "@element-plus/icons-vue";
|
import { Switch, Check } from "@element-plus/icons-vue";
|
||||||
import { Option } from "@/types";
|
import { Option } from "@/types";
|
||||||
|
|
||||||
@@ -49,7 +31,9 @@ const emit = defineEmits(["menuClick"]);
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
role: {
|
role: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -57,7 +41,7 @@ const menuRef = ref(ElTree); // 属性名必须和元素的ref属性值一致
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.role.id as any,
|
() => props.role.id as any,
|
||||||
(newVal, oldVal) => {
|
() => {
|
||||||
const roleId = props.role.id;
|
const roleId = props.role.id;
|
||||||
if (roleId) {
|
if (roleId) {
|
||||||
state.checkStrictly = true;
|
state.checkStrictly = true;
|
||||||
|
|||||||
@@ -3,69 +3,54 @@
|
|||||||
<div v-if="permissionOptions.length > 0">
|
<div v-if="permissionOptions.length > 0">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-checkbox
|
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选
|
||||||
:indeterminate="isIndeterminate"
|
|
||||||
v-model="checkAll"
|
|
||||||
@change="handleCheckAllChange"
|
|
||||||
>全选
|
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12" style="text-align: right">
|
<el-col :span="12" style="text-align: right">
|
||||||
<el-button type="primary" :icon="Check" @click="handleSubmit"
|
<el-button type="primary" :icon="Check" @click="handleSubmit">提交</el-button>
|
||||||
>提交</el-button
|
|
||||||
>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col
|
<el-col :span="8" v-for="item in permissionOptions" style="margin-top: 20px" :key="item.id">
|
||||||
:span="8"
|
<el-checkbox border v-model="item.checked" :label="item.id" :key="item.id" @change="handleCheckedPermChange">
|
||||||
v-for="item in permissionOptions"
|
|
||||||
style="margin-top: 20px"
|
|
||||||
:key="item.id"
|
|
||||||
>
|
|
||||||
<el-checkbox
|
|
||||||
border
|
|
||||||
v-model="item.checked"
|
|
||||||
:label="item.id"
|
|
||||||
:key="item.id"
|
|
||||||
@change="handleCheckedPermChange"
|
|
||||||
>
|
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: center" v-else>
|
<div style="text-align: center" v-else>
|
||||||
<el-empty
|
<el-empty :description="
|
||||||
:description="
|
!role
|
||||||
!role
|
? '请选择角色'
|
||||||
? '请选择角色'
|
: !menu
|
||||||
: !menu
|
|
||||||
? '请选择菜单'
|
? '请选择菜单'
|
||||||
: '暂无数据,您可在【菜单管理】配置权限数据'
|
: '暂无数据,您可在【菜单管理】配置权限数据'
|
||||||
"
|
"></el-empty>
|
||||||
></el-empty>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, toRefs, watch } from "vue";
|
||||||
import { listPerms } from "@/api/system/perm";
|
import { listPerms } from "@/api/system/perm";
|
||||||
import { listRolePerms, saveRolePerms } from "@/api/system/role";
|
import { listRolePerms, saveRolePerms } from "@/api/system/role";
|
||||||
import { onMounted, reactive, toRefs, watch } from "vue";
|
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { Check } from "@element-plus/icons-vue";
|
import { Check } from "@element-plus/icons-vue";
|
||||||
import { PermQueryParam, MenuItem } from "@/types";
|
import { PermQueryParam } from "@/types";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
role: {
|
role: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
menu: {
|
menu: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -86,10 +71,9 @@ const state = reactive({
|
|||||||
checkedPerms: [],
|
checkedPerms: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { permissionOptions, isIndeterminate, checkAll, checkedPerms } =
|
const { permissionOptions, isIndeterminate, checkAll } = toRefs(state);
|
||||||
toRefs(state);
|
|
||||||
|
|
||||||
function handleCheckAllChange(checked: Boolean) {
|
function handleCheckAllChange(checked: boolean) {
|
||||||
state.isIndeterminate = false;
|
state.isIndeterminate = false;
|
||||||
if (checked) {
|
if (checked) {
|
||||||
state.permissionOptions.map((item) => (item.checked = true));
|
state.permissionOptions.map((item) => (item.checked = true));
|
||||||
@@ -99,7 +83,7 @@ function handleCheckAllChange(checked: Boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCheckedPermChange(value: any) {
|
function handleCheckedPermChange() {
|
||||||
const checkedCount = state.permissionOptions.filter(
|
const checkedCount = state.permissionOptions.filter(
|
||||||
(item) => item.checked
|
(item) => item.checked
|
||||||
).length;
|
).length;
|
||||||
@@ -116,7 +100,7 @@ function loadData() {
|
|||||||
state.loading = true;
|
state.loading = true;
|
||||||
|
|
||||||
const params = { menuId: props.menu.id } as PermQueryParam;
|
const params = { menuId: props.menu.id } as PermQueryParam;
|
||||||
listPerms(params).then(({data}) => {
|
listPerms(params).then(({ data }) => {
|
||||||
state.permissionOptions = data;
|
state.permissionOptions = data;
|
||||||
listRolePerms(props.role.id, props.menu.id).then((response) => {
|
listRolePerms(props.role.id, props.menu.id).then((response) => {
|
||||||
const checkedPermIds = response.data;
|
const checkedPermIds = response.data;
|
||||||
@@ -150,6 +134,7 @@ function resetData() {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadData();
|
loadData();
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -3,90 +3,41 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||||
>新增</el-button
|
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
<el-input
|
<el-input v-model="queryParams.name" placeholder="角色名称" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="queryParams.name"
|
|
||||||
placeholder="角色名称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<!-- 数据表格 -->
|
||||||
<el-table
|
<el-table ref="dataTableRef" v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"
|
||||||
ref="dataTableRef"
|
@row-click="handleRowClick" highlight-current-row border>
|
||||||
v-loading="loading"
|
|
||||||
:data="roleList"
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
@row-click="handleRowClick"
|
|
||||||
highlight-current-row
|
|
||||||
border
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column label="角色名称" prop="name" />
|
<el-table-column label="角色名称" prop="name" />
|
||||||
<el-table-column label="角色编码" prop="code" />
|
<el-table-column label="角色编码" prop="code" />
|
||||||
<el-table-column label="操作" align="center" width="120">
|
<el-table-column label="操作" align="center" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||||
type="primary"
|
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||||
:icon="Edit"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleUpdate(scope.row)"
|
|
||||||
/>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
circle
|
|
||||||
plain
|
|
||||||
@click.stop="handleDelete(scope.row)"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页工具条 -->
|
<!-- 分页工具条 -->
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNum"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 表单弹窗 -->
|
<!-- 表单弹窗 -->
|
||||||
<el-dialog
|
<el-dialog :title="dialog.title" v-model="dialog.visible" @close="cancel" width="450px">
|
||||||
:title="dialog.title"
|
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||||
v-model="dialog.visible"
|
|
||||||
@close="cancel"
|
|
||||||
width="450px"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="dataFormRef"
|
|
||||||
:model="formData"
|
|
||||||
:rules="rules"
|
|
||||||
label-width="100px"
|
|
||||||
>
|
|
||||||
<el-form-item label="角色名称" prop="name">
|
<el-form-item label="角色名称" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入角色名称" />
|
<el-input v-model="formData.name" placeholder="请输入角色名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -96,12 +47,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="排序" prop="sort">
|
<el-form-item label="排序" prop="sort">
|
||||||
<el-input-number
|
<el-input-number v-model="formData.sort" controls-position="right" :min="0" style="width: 100px" />
|
||||||
v-model="formData.sort"
|
|
||||||
controls-position="right"
|
|
||||||
:min="0"
|
|
||||||
style="width: 100px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="状态">
|
<el-form-item label="状态">
|
||||||
@@ -123,6 +69,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { onMounted, reactive, ref, toRefs, defineEmits } from "vue";
|
||||||
import {
|
import {
|
||||||
listRolePages,
|
listRolePages,
|
||||||
updateRole,
|
updateRole,
|
||||||
@@ -130,7 +77,6 @@ import {
|
|||||||
addRole,
|
addRole,
|
||||||
deleteRoles,
|
deleteRoles,
|
||||||
} from "@/api/system/role";
|
} from "@/api/system/role";
|
||||||
import { onMounted, reactive, ref, toRefs, unref } from "vue";
|
|
||||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||||
import { RoleFormData, RoleItem, RoleQueryParam } from "@/types";
|
import { RoleFormData, RoleItem, RoleQueryParam } from "@/types";
|
||||||
@@ -166,7 +112,6 @@ const state = reactive({
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
queryParams,
|
queryParams,
|
||||||
roleList,
|
roleList,
|
||||||
@@ -224,16 +169,16 @@ function submitForm() {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateRole(state.formData.id as any, state.formData).then(
|
updateRole(state.formData.id as any, state.formData).then(
|
||||||
(response) => {
|
() => {
|
||||||
ElMessage.success("修改成功");
|
ElMessage.success("修改成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
addRole(state.formData).then((response) => {
|
addRole(state.formData).then(() => {
|
||||||
ElMessage.success("新增成功");
|
ElMessage.success("新增成功");
|
||||||
state.dialog.visible = false;
|
cancel();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -244,14 +189,9 @@ function submitForm() {
|
|||||||
/**
|
/**
|
||||||
* 重置表单
|
* 重置表单
|
||||||
*/
|
*/
|
||||||
function resetForm() {
|
|
||||||
dataFormRef.value.resetFields();
|
|
||||||
handleQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancel() {
|
function cancel() {
|
||||||
resetForm();
|
|
||||||
state.dialog.visible = false;
|
state.dialog.visible = false;
|
||||||
|
dataFormRef.value.resetFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete(row: any) {
|
function handleDelete(row: any) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<svg-icon color="#333" icon-class="role" />
|
<svg-icon color="#333" icon-class="role" />
|
||||||
角色列表
|
角色列表
|
||||||
</template>
|
</template>
|
||||||
<role ref="role" @roleClick="handleRoleClick" />
|
<Role ref="role" @roleClick="handleRoleClick" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag type="warning" v-else size="small">请选择角色</el-tag>
|
<el-tag type="warning" v-else size="small">请选择角色</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<menus ref="menu" @menuClick="handleMenuClick" :role="role" />
|
<Menus ref="menu" @menuClick="handleMenuClick" :role="role" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ import { listSelectDepartments } from "@/api/system/dept";
|
|||||||
import { listRoles } from "@/api/system/role";
|
import { listRoles } from "@/api/system/role";
|
||||||
|
|
||||||
// 组件依赖
|
// 组件依赖
|
||||||
import { ElMessage, ElMessageBox, ElTree, ElForm, UploadRequestOptions } from "element-plus";
|
import { ElMessage, ElMessageBox, ElTree, ElForm, UploadFile } from "element-plus";
|
||||||
import {
|
import {
|
||||||
Search,
|
Search,
|
||||||
Plus,
|
Plus,
|
||||||
@@ -234,7 +234,6 @@ import {
|
|||||||
Dialog,
|
Dialog,
|
||||||
UserImportFormData
|
UserImportFormData
|
||||||
} from "@/types";
|
} from "@/types";
|
||||||
import { assertFile } from "@babel/types";
|
|
||||||
|
|
||||||
// DOM元素的引用声明定义 ,变量名和DOM的ref属性值一致
|
// DOM元素的引用声明定义 ,变量名和DOM的ref属性值一致
|
||||||
const deptTreeRef = ref(ElTree); // 部门树
|
const deptTreeRef = ref(ElTree); // 部门树
|
||||||
@@ -312,7 +311,6 @@ const state = reactive({
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
single,
|
|
||||||
multiple,
|
multiple,
|
||||||
queryParams,
|
queryParams,
|
||||||
userList,
|
userList,
|
||||||
@@ -444,7 +442,7 @@ function resetPassword(row: { [key: string]: any }) {
|
|||||||
ElMessage.success("修改成功,新密码是:" + value);
|
ElMessage.success("修改成功,新密码是:" + value);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => { });
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -489,7 +487,7 @@ function submitForm() {
|
|||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addUser(state.formData).then((response: any) => {
|
addUser(state.formData).then(() => {
|
||||||
ElMessage.success("新增用户成功");
|
ElMessage.success("新增用户成功");
|
||||||
cancel()
|
cancel()
|
||||||
handleQuery();
|
handleQuery();
|
||||||
@@ -576,8 +574,7 @@ async function showImportDialog() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleExcelChange(file: any, fileList: File[]) {
|
function handleExcelChange(file: UploadFile) {
|
||||||
const fileName = file.name;
|
|
||||||
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
|
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
|
||||||
ElMessage.warning('上传Excel只能为xlsx、xls格式');
|
ElMessage.warning('上传Excel只能为xlsx、xls格式');
|
||||||
state.excelFile = undefined
|
state.excelFile = undefined
|
||||||
|
|||||||
@@ -2,54 +2,35 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-input
|
<el-input v-model="queryParams.nickName" placeholder="会员昵称" clearable @keyup.enter="handleQuery" />
|
||||||
v-model="queryParams.nickName"
|
|
||||||
placeholder="会员昵称"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-table
|
<el-table v-loading="loading" :data="memberList" border @selection-change="handleSelectionChange">
|
||||||
v-loading="loading"
|
|
||||||
:data="memberList"
|
|
||||||
border
|
|
||||||
@selection-change="handleSelectionChange"
|
|
||||||
>
|
|
||||||
<el-table-column type="selection" align="center" />
|
<el-table-column type="selection" align="center" />
|
||||||
<el-table-column type="expand" width="120" label="会员地址">
|
<el-table-column type="expand" width="120" label="会员地址">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-table :data="scope.row.addressList" size="small" border>
|
<el-table :data="scope.row.addressList" size="small" border>
|
||||||
<el-table-column
|
<el-table-column type="index" label="序号" width="100" align="center" />
|
||||||
type="index"
|
|
||||||
label="序号"
|
|
||||||
width="100"
|
|
||||||
align="center"
|
|
||||||
/>
|
|
||||||
<el-table-column align="center" label="收货人" prop="name" />
|
<el-table-column align="center" label="收货人" prop="name" />
|
||||||
<el-table-column align="center" label="联系方式" prop="mobile" />
|
<el-table-column align="center" label="联系方式" prop="mobile" />
|
||||||
<el-table-column align="center" label="收货地址">
|
<el-table-column align="center" label="收货地址">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{
|
{{
|
||||||
scope.row.province +
|
scope.row.province +
|
||||||
scope.row.city +
|
scope.row.city +
|
||||||
scope.row.area +
|
scope.row.area +
|
||||||
scope.row.address
|
scope.row.address
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="邮编" prop="zipCode" />
|
<el-table-column align="center" label="邮编" prop="zipCode" />
|
||||||
<el-table-column align="center" label="是否默认">
|
<el-table-column align="center" label="是否默认">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.defaulted == 1" type="success"
|
<el-tag v-if="scope.row.defaulted == 1" type="success">是</el-tag>
|
||||||
>是</el-tag
|
|
||||||
>
|
|
||||||
<el-tag v-if="scope.row.defaulted == 0" type="info">否</el-tag>
|
<el-tag v-if="scope.row.defaulted == 0" type="info">否</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -71,10 +52,7 @@
|
|||||||
<el-popover placement="right" :width="400" trigger="hover">
|
<el-popover placement="right" :width="400" trigger="hover">
|
||||||
<img :src="scope.row.avatarUrl" width="400" height="400" />
|
<img :src="scope.row.avatarUrl" width="400" height="400" />
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<img
|
<img :src="scope.row.avatarUrl" style="max-height: 60px; max-width: 60px" />
|
||||||
:src="scope.row.avatarUrl"
|
|
||||||
style="max-height: 60px; max-width: 60px"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
@@ -98,23 +76,18 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页工具条 -->
|
<!-- 分页工具条 -->
|
||||||
<pagination
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||||
v-show="total > 0"
|
@pagination="handleQuery" />
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNum"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
@pagination="handleQuery"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, toRefs } from "vue";
|
import { reactive, onMounted, toRefs } from "vue";
|
||||||
import { ElTable, ElMessage, ElMessageBox } from "element-plus";
|
import { ElTable } from "element-plus";
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
import { Search, Refresh } from "@element-plus/icons-vue";
|
||||||
|
|
||||||
import { listMemeberPages } from "@/api/ums/member";
|
import { listMemeberPages } from "@/api/ums/member";
|
||||||
import { MemberQueryParam,MemberItem } from "@/types";
|
import { MemberQueryParam, MemberItem } from "@/types";
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
@@ -128,17 +101,17 @@ const state = reactive({
|
|||||||
total: 0,
|
total: 0,
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10
|
||||||
} as MemberQueryParam,
|
} as MemberQueryParam,
|
||||||
memberList: [] as MemberItem[]
|
memberList: [] as MemberItem[]
|
||||||
});
|
});
|
||||||
|
|
||||||
const { loading, ids, single, multiple, queryParams, memberList, total } =
|
const { loading, queryParams, memberList, total } =
|
||||||
toRefs(state);
|
toRefs(state);
|
||||||
|
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
listMemeberPages(state.queryParams).then(({data}) => {
|
listMemeberPages(state.queryParams).then(({ data }) => {
|
||||||
state.memberList = data.list;
|
state.memberList = data.list;
|
||||||
state.total = data.total;
|
state.total = data.total;
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
@@ -149,7 +122,7 @@ function resetQuery() {
|
|||||||
state.queryParams = {
|
state.queryParams = {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
nickName: undefined,
|
nickName: ''
|
||||||
};
|
};
|
||||||
handleQuery();
|
handleQuery();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user