refactor: 所有业务线的接口调用添加TypeScript类型声明描述
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ClientFormData, ClientPageResult, ClientQueryParam } from '@/types/api/client'
|
||||
import { ClientFormData, ClientPageResult, ClientQueryParam } from '@/types/api/system/client'
|
||||
import request from '@/utils/request'
|
||||
import { AxiosPromise } from 'axios'
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import request from '@/utils/request'
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
export function uploadFile(file: any) {
|
||||
export function uploadFile(file: File) {
|
||||
let formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return request(
|
||||
@@ -24,7 +24,7 @@ export function uploadFile(file: any) {
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
export function deleteFile(path: string) {
|
||||
export function deleteFile(path?: string) {
|
||||
return request({
|
||||
url: '/youlai-admin/api/v1/files',
|
||||
method: 'delete',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PermFormData, PermItem, PermPageResult, PermQueryParam } from '@/types'
|
||||
import request from '@/utils/request'
|
||||
import { Axios, AxiosPromise } from 'axios'
|
||||
import { AxiosPromise } from 'axios'
|
||||
|
||||
/**
|
||||
* 获取权限分页列表
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { MemberPageResult, MemberQueryParam } from '@/types'
|
||||
import request from '@/utils/request'
|
||||
import { AxiosPromise } from 'axios'
|
||||
|
||||
/**
|
||||
* 获取会员分页列表
|
||||
*
|
||||
* @param queryParams
|
||||
*/
|
||||
export function listMembersWithPage(queryParams:object) {
|
||||
export function listMemeberPages(queryParams: MemberQueryParam): AxiosPromise<MemberPageResult> {
|
||||
return request({
|
||||
url: '/mall-ums/api/v1/members',
|
||||
method: 'get',
|
||||
@@ -18,7 +20,7 @@ export function listMembersWithPage(queryParams:object) {
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
export function getMemberDetail(id:number) {
|
||||
export function getMemberFormDetail(id: number) {
|
||||
return request({
|
||||
url: '/mall-ums/api/v1/members/' + id,
|
||||
method: 'get'
|
||||
@@ -30,7 +32,7 @@ export function getMemberDetail(id:number) {
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
export function addMember(data:object) {
|
||||
export function addMember(data: object) {
|
||||
return request({
|
||||
url: '/mall-ums/api/v1/members',
|
||||
method: 'post',
|
||||
@@ -44,7 +46,7 @@ export function addMember(data:object) {
|
||||
* @param id
|
||||
* @param data
|
||||
*/
|
||||
export function updateMember(id:number, data:object) {
|
||||
export function updateMember(id: number, data: object) {
|
||||
return request({
|
||||
url: '/mall-ums/api/v1/members/' + id,
|
||||
method: 'put',
|
||||
|
||||
@@ -1,61 +1,70 @@
|
||||
<template>
|
||||
<div class="component-container">
|
||||
<div>
|
||||
<!-- 上传组件 -->
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
action=""
|
||||
class="single-uploader"
|
||||
list-type="picture-card"
|
||||
:show-file-list="false"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:on-exceed="handleExceed"
|
||||
:limit="1"
|
||||
:http-request="uploadImage"
|
||||
ref="singleUploadRef"
|
||||
class="single-uploader"
|
||||
:show-file-list="false"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:on-exceed="handleExceed"
|
||||
:http-request="uploadImage"
|
||||
>
|
||||
<img v-if="imgUrl" :src="imgUrl" class="single-uploader-image"/>
|
||||
<img v-if="imgUrl" :src="imgUrl" class="single-uploader__image" />
|
||||
|
||||
<el-icon v-else class="single-uploader-icon">
|
||||
<Plus/>
|
||||
<el-icon v-else class="single-uploader__plus">
|
||||
<Plus />
|
||||
</el-icon>
|
||||
|
||||
<!-- 删除图标 -->
|
||||
<el-icon
|
||||
v-if="imgUrl"
|
||||
class="single-uploader-remove-icon"
|
||||
@click.stop="handleRemove(imgUrl)"
|
||||
v-if="props.showClose && imgUrl"
|
||||
class="single-uploader__remove"
|
||||
@click.stop="handleRemove(imgUrl)"
|
||||
>
|
||||
<Close/>
|
||||
<Close />
|
||||
</el-icon>
|
||||
</el-upload>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, ref} from "vue";
|
||||
import {Plus, Close} from '@element-plus/icons-vue'
|
||||
import {ElMessage, ElUpload, UploadFile, UploadRequestOptions} from "element-plus"
|
||||
import {uploadFile, deleteFile} from "@/api/system/file";
|
||||
import { computed, ref } from "vue";
|
||||
import { Plus, Close } from "@element-plus/icons-vue";
|
||||
import {
|
||||
ElMessage,
|
||||
ElUpload,
|
||||
UploadFile,
|
||||
UploadRawFile,
|
||||
UploadRequestOptions,
|
||||
} from "element-plus";
|
||||
import { uploadFile, deleteFile } from "@/api/system/file";
|
||||
|
||||
const uploadRef = ref(ElUpload)
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
const uploadRef = ref(ElUpload);
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
default: "",
|
||||
},
|
||||
/**
|
||||
* 是否显示右上角的删除图片按钮
|
||||
*/
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const imgUrl = computed<string | null>({
|
||||
get() {
|
||||
return props.modelValue
|
||||
return props.modelValue;
|
||||
},
|
||||
set(val) {
|
||||
// imgUrl改变时触发修改父组件绑定的v-model的值
|
||||
emit('update:modelValue', val)
|
||||
}
|
||||
})
|
||||
|
||||
emit("update:modelValue", val);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 自定义图片上传
|
||||
@@ -63,24 +72,8 @@ const imgUrl = computed<string | null>({
|
||||
* @param params
|
||||
*/
|
||||
async function uploadImage(options: UploadRequestOptions): Promise<any> {
|
||||
const response=await uploadFile(options.file);
|
||||
imgUrl.value=response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后选择文件覆盖前面的文件
|
||||
*
|
||||
* Set limit and on-exceed to automatically replace the previous file when select a new file.
|
||||
*
|
||||
* @param files
|
||||
*/
|
||||
|
||||
function handleExceed(files: File[], uploadFiles: UploadFile[]) {
|
||||
uploadRef.value.clearFiles()
|
||||
uploadRef.value.handleStart(files[0])
|
||||
uploadFile(files[0]).then(response => {
|
||||
imgUrl.value = response.data
|
||||
})
|
||||
const response = await uploadFile(options.file);
|
||||
imgUrl.value = response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,61 +81,62 @@ function handleExceed(files: File[], uploadFiles: UploadFile[]) {
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
function handleRemove(file: string | null) {
|
||||
function handleRemove(file: UploadFile, fileList: UploadFile[]) {
|
||||
if (file) {
|
||||
deleteFile(file)
|
||||
imgUrl.value = null // 这里会触发imgUrl的computed的set方法
|
||||
deleteFile(file.url);
|
||||
imgUrl.value = null; // 这里会触发imgUrl的computed的set方法
|
||||
}
|
||||
}
|
||||
|
||||
function handleBeforeUpload(file: any) {
|
||||
const isJPG = file.type === 'image/jpeg'
|
||||
const isLt2M = file.size / 1024 / 1024 < 2
|
||||
/* if (!isJPG) {
|
||||
ElMessage.warning("此文件非图片文件")
|
||||
return false
|
||||
}*/
|
||||
/**
|
||||
* 在 before-upload 钩子中限制用户上传文件的格式和大小
|
||||
*
|
||||
*/
|
||||
function handleBeforeUpload(file: UploadRawFile) {
|
||||
const isJPG = file.type === "image/jpeg";
|
||||
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
|
||||
if (!isLt2M) {
|
||||
ElMessage.warning("上传图片不能大于2M")
|
||||
ElMessage.warning("上传图片不能大于2M");
|
||||
}
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.single-uploader {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: var(--el-transition-duration-fast);
|
||||
text-align: center;
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.component-container {
|
||||
.single-uploader {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
&__image {
|
||||
width: 146px;
|
||||
height: 146px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: #409EFF;
|
||||
}
|
||||
&__plus {
|
||||
width: 146px;
|
||||
height: 157px;
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-image {
|
||||
width: 146px;
|
||||
height: 146px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&-remove-icon {
|
||||
font-size: 12px;
|
||||
color: #ff4d51 !important;
|
||||
margin-top: 0px !important;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
color: #409eff;
|
||||
}
|
||||
&__remove {
|
||||
font-size: 12px;
|
||||
color: #ff4d51 !important;
|
||||
margin-top: 0px !important;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
6
src/types/api/index.d.ts
vendored
Normal file
6
src/types/api/index.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
export * from './system'
|
||||
export * from './pms'
|
||||
export * from './sms'
|
||||
export * from './ums'
|
||||
export * from './oms'
|
||||
58
src/types/api/oms/order.d.ts
vendored
Normal file
58
src/types/api/oms/order.d.ts
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 订单查询参数类型声明
|
||||
*/
|
||||
export interface OrderQueryParam extends PageQueryParam {
|
||||
orderSn: string | undefined;
|
||||
status: number | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单分页列表项声明
|
||||
*/
|
||||
export interface Order {
|
||||
id: string;
|
||||
orderSn: string;
|
||||
totalAmount: string;
|
||||
payAmount: string;
|
||||
payType: number;
|
||||
status: number;
|
||||
totalQuantity: number;
|
||||
gmtCreate: string;
|
||||
memberId: string;
|
||||
sourceType: number;
|
||||
orderItems: OrderItem[];
|
||||
}
|
||||
export interface OrderItem {
|
||||
id: string;
|
||||
orderId: string;
|
||||
skuId: string;
|
||||
skuName: string;
|
||||
picUrl: string;
|
||||
price: string;
|
||||
count: number;
|
||||
totalAmount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单分页项类型声明
|
||||
*/
|
||||
export interface OrderPageResult extends PageResult<Order[]> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单表单类型声明
|
||||
*/
|
||||
export interface OrderDetail {
|
||||
id: number | undefined;
|
||||
title: string;
|
||||
picUrl: string;
|
||||
beginTime: string;
|
||||
endTime: string;
|
||||
status: number;
|
||||
sort: number;
|
||||
url: string;
|
||||
remark: string;
|
||||
}
|
||||
36
src/types/api/pms/brand.d.ts
vendored
Normal file
36
src/types/api/pms/brand.d.ts
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 品牌查询参数类型声明
|
||||
*/
|
||||
export interface BrandQueryParam extends PageQueryParam {
|
||||
name: String | undefined
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 品牌分页列表项声明
|
||||
*/
|
||||
export interface BrandItem {
|
||||
id: string;
|
||||
name: string;
|
||||
logoUrl: string;
|
||||
sort: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 品牌分页项类型声明
|
||||
*/
|
||||
export interface BrandPageResult extends PageResult<BrandItem[]> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 品牌表单类型声明
|
||||
*/
|
||||
export interface BrandFormData {
|
||||
id: number | undefined,
|
||||
name: string,
|
||||
logoUrl: string,
|
||||
sort: number
|
||||
}
|
||||
73
src/types/api/pms/goods.d.ts
vendored
Normal file
73
src/types/api/pms/goods.d.ts
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
|
||||
/**
|
||||
* 商品查询参数类型声明
|
||||
*/
|
||||
export interface GoodsQueryParam extends PageQueryParam {
|
||||
name: stirng | undefined,
|
||||
categoryId: number | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品列表项类型声明
|
||||
*/
|
||||
export interface GoodsItem {
|
||||
id: string;
|
||||
name: string;
|
||||
categoryId?: any;
|
||||
brandId?: any;
|
||||
originPrice: string;
|
||||
price: string;
|
||||
sales: number;
|
||||
picUrl?: any;
|
||||
album?: any;
|
||||
unit?: any;
|
||||
description: string;
|
||||
detail: string;
|
||||
status?: any;
|
||||
categoryName: string;
|
||||
brandName: string;
|
||||
skuList: SkuItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品规格项类型声明
|
||||
*/
|
||||
export interface SkuItem {
|
||||
id: string;
|
||||
skuSn?: any;
|
||||
name: string;
|
||||
spuId?: any;
|
||||
specIds: string;
|
||||
price: string;
|
||||
stockNum: number;
|
||||
lockedStockNum?: any;
|
||||
picUrl?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品分页项类型声明
|
||||
*/
|
||||
export interface GoodsPageResult extends PageResult<GoodsItem[]> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品表单数据类型声明
|
||||
*/
|
||||
export interface GoodsFormData {
|
||||
id: number|undefined,
|
||||
deptId: number,
|
||||
username: string,
|
||||
nickname: string,
|
||||
password: string,
|
||||
mobile: string,
|
||||
email: string,
|
||||
gender: number,
|
||||
status: number,
|
||||
remark: string,
|
||||
roleIds: number[]
|
||||
}
|
||||
|
||||
|
||||
40
src/types/api/sms/advert.d.ts
vendored
Normal file
40
src/types/api/sms/advert.d.ts
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 广告查询参数类型声明
|
||||
*/
|
||||
export interface AdvertQueryParam extends PageQueryParam {
|
||||
name: String | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告分页列表项声明
|
||||
*/
|
||||
export interface AdvertItem {
|
||||
id: string;
|
||||
name: string;
|
||||
logoUrl: string;
|
||||
sort: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告分页项类型声明
|
||||
*/
|
||||
export interface AdvertPageResult extends PageResult<AdvertItem[]> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 广告表单类型声明
|
||||
*/
|
||||
export interface AdvertFormData {
|
||||
id: number | undefined;
|
||||
title: string;
|
||||
picUrl: string;
|
||||
beginTime: string;
|
||||
endTime: string;
|
||||
status: number;
|
||||
sort: number;
|
||||
url: string;
|
||||
remark: string;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PageQueryParam, PageResult } from "./base"
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 客户端查询参数类型声明
|
||||
@@ -28,7 +28,7 @@ export interface DeptItem {
|
||||
* 部门表单类型声明
|
||||
*/
|
||||
export interface DeptFormData {
|
||||
id: number,
|
||||
id: number|undefined,
|
||||
parentId: number,
|
||||
name: string,
|
||||
sort: number,
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PageQueryParam, PageResult } from "./base"
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 字典查询参数类型声明
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PageQueryParam, PageResult } from "./base"
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 权限查询参数类型声明
|
||||
@@ -31,7 +31,7 @@ export interface PermPageResult extends PageResult<PermItem[]> {
|
||||
* 权限表单类型声明
|
||||
*/
|
||||
export interface PermFormData {
|
||||
id: number,
|
||||
id: number|undefined,
|
||||
name: string,
|
||||
urlPerm: string,
|
||||
btnPerm: string,
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PageQueryParam, PageResult } from "./base"
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 角色查询参数类型声明
|
||||
@@ -33,7 +33,7 @@ export interface RolePageResult extends PageResult<RoleItem[]> {
|
||||
* 角色表单类型声明
|
||||
*/
|
||||
export interface RoleFormData {
|
||||
id: number,
|
||||
id: number|undefined,
|
||||
name: string,
|
||||
code: string,
|
||||
sort: number,
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PageQueryParam, PageResult } from "./base"
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 用户信息类型声明
|
||||
@@ -48,7 +48,7 @@ export interface UserPageResult extends PageResult<UserItem[]> {
|
||||
* 用户表单类型声明
|
||||
*/
|
||||
export interface UserFormData {
|
||||
id: number,
|
||||
id: number | undefined,
|
||||
deptId: number,
|
||||
username: string,
|
||||
nickname: string,
|
||||
1
src/types/api/ums/index.d.ts
vendored
Normal file
1
src/types/api/ums/index.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from './member'
|
||||
66
src/types/api/ums/member.d.ts
vendored
Normal file
66
src/types/api/ums/member.d.ts
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
import { PageQueryParam, PageResult } from "../base"
|
||||
|
||||
/**
|
||||
* 会员查询参数类型声明
|
||||
*/
|
||||
export interface MemberQueryParam extends PageQueryParam {
|
||||
nickName: String | undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员分页列表项声明
|
||||
*/
|
||||
export interface MemberItem {
|
||||
id: string;
|
||||
gender: number;
|
||||
nickName: string;
|
||||
mobile: string;
|
||||
birthday?: any;
|
||||
avatarUrl: string;
|
||||
openid: string;
|
||||
sessionKey?: any;
|
||||
city: string;
|
||||
country: string;
|
||||
language: string;
|
||||
province: string;
|
||||
status: number;
|
||||
balance: string;
|
||||
deleted: number;
|
||||
point: number;
|
||||
addressList: AddressItem[];
|
||||
}
|
||||
|
||||
export interface AddressItem {
|
||||
id: string;
|
||||
memberId: string;
|
||||
consigneeName: string;
|
||||
consigneeMobile: string;
|
||||
province: string;
|
||||
city: string;
|
||||
area: string;
|
||||
detailAddress: string;
|
||||
zipCode?: any;
|
||||
defaulted: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员分页项类型声明
|
||||
*/
|
||||
export interface MemberPageResult extends PageResult<MemberItem[]> {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员表单类型声明
|
||||
*/
|
||||
export interface MemberFormData {
|
||||
id: number | undefined;
|
||||
title: string;
|
||||
picUrl: string;
|
||||
beginTime: string;
|
||||
endTime: string;
|
||||
status: number;
|
||||
sort: number;
|
||||
url: string;
|
||||
remark: string;
|
||||
}
|
||||
27
src/types/index.d.ts
vendored
27
src/types/index.d.ts
vendored
@@ -1,12 +1,21 @@
|
||||
export * from './api/login'
|
||||
export * from './api/user'
|
||||
export * from './api/role'
|
||||
export * from './api/menu'
|
||||
export * from './api/dept'
|
||||
export * from './api/dict'
|
||||
export * from './api/perm'
|
||||
export * from './api/client'
|
||||
|
||||
export * from './api/system/login'
|
||||
export * from './api/system/user'
|
||||
export * from './api/system/role'
|
||||
export * from './api/system/menu'
|
||||
export * from './api/system/dept'
|
||||
export * from './api/system/dict'
|
||||
export * from './api/system/perm'
|
||||
export * from './api/system/client'
|
||||
|
||||
|
||||
export * from './component'
|
||||
export * from './api/pms/goods'
|
||||
export * from './api/pms/goods'
|
||||
|
||||
export * from './api/sms/advert'
|
||||
|
||||
export * from './api/oms/order'
|
||||
|
||||
|
||||
export * from './common'
|
||||
|
||||
|
||||
@@ -1,79 +1,70 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form
|
||||
ref="queryForm"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
>
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item prop="orderSn">
|
||||
<el-input v-model="queryParams.orderSn" placeholder="订单号"/>
|
||||
<el-input v-model="queryParams.orderSn" placeholder="订单号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
style="width: 240px"
|
||||
value-format="yyyy-MM-dd"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
v-model="dateRange"
|
||||
style="width: 240px"
|
||||
value-format="yyyy-MM-dd"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-select
|
||||
v-model="queryParams.status"
|
||||
class="filter-item"
|
||||
placeholder="订单状态"
|
||||
v-model="queryParams.status"
|
||||
class="filter-item"
|
||||
placeholder="订单状态"
|
||||
>
|
||||
<el-option
|
||||
v-for="(key, value) in orderStatusMap"
|
||||
:label="key"
|
||||
:value="value"
|
||||
v-for="(key, value) in orderStatusMap"
|
||||
:key="key"
|
||||
:label="key"
|
||||
:value="value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">查询</el-button>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
||||
>查询</el-button
|
||||
>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table
|
||||
ref="dataTable"
|
||||
v-loading="loading"
|
||||
:data="pageList"
|
||||
border
|
||||
>
|
||||
<el-table ref="dataTable" v-loading="loading" :data="orderList" border>
|
||||
<el-table-column type="expand" width="100" label="订单商品">
|
||||
<template #default="scope">
|
||||
<el-table
|
||||
:data="scope.row.orderItems"
|
||||
border
|
||||
>
|
||||
<el-table-column label="序号" type="index" width="100"/>
|
||||
<el-table-column label="商品编号" align="center" prop="skuSn"/>
|
||||
<el-table-column label="商品规格" align="center" prop="skuName"/>
|
||||
<el-table :data="scope.row.orderItems" border>
|
||||
<el-table-column label="序号" type="index" width="100" />
|
||||
<el-table-column label="商品编号" align="center" prop="skuSn" />
|
||||
<el-table-column label="商品规格" align="center" prop="skuName" />
|
||||
<el-table-column label="图片" prop="picUrl">
|
||||
<template slot-scope="scope">
|
||||
<img :src="scope.row.picUrl" width="40">
|
||||
<template #default="scope">
|
||||
<img :src="scope.row.picUrl" width="40" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="单价" prop="price">
|
||||
<template slot-scope="scope">{{ scope.row.price}}</template>
|
||||
<template #default="scope">{{ scope.row.price }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="数量" prop="count">
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
<template #default="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" prop="orderSn" label="订单编号"/>
|
||||
<el-table-column align="center" prop="orderSn" label="订单编号" />
|
||||
|
||||
<el-table-column align="center" prop="memberId" label="会员ID"/>
|
||||
<el-table-column align="center" prop="memberId" label="会员ID" />
|
||||
|
||||
<el-table-column align="center" label="订单来源">
|
||||
<template #default="scope">
|
||||
@@ -95,17 +86,17 @@
|
||||
|
||||
<el-table-column align="center" prop="payPrice" label="支付金额">
|
||||
<template #default="scope">
|
||||
{{ scope.row.payAmount }}
|
||||
{{ scope.row.payAmount }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="支付方式">
|
||||
<template #default="scope">
|
||||
<el-tag>{{ scope.row.payType }}</el-tag>
|
||||
<el-tag>{{ scope.row.payType }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" prop="gmtCreate" label="创建时间"/>
|
||||
<el-table-column align="center" prop="gmtCreate" label="创建时间" />
|
||||
|
||||
<el-table-column align="center" label="操作">
|
||||
<template #default="scope">
|
||||
@@ -116,50 +107,49 @@
|
||||
|
||||
<!-- 分页工具条 -->
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { Dialog, Order, OrderQueryParam } from "@/types";
|
||||
import { listOrderPages, getOrderDetail } from "@/api/oms/order";
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
|
||||
import {listOrdersWithPage, getOrderDetail} from '@/api/oms/order'
|
||||
import {onMounted, reactive, ref, toRefs} from "vue"
|
||||
import {ElForm, ElMessage, ElMessageBox} from "element-plus"
|
||||
import {Search, Plus, Edit, Refresh, Delete} from '@element-plus/icons-vue'
|
||||
|
||||
const dataForm = ref(ElForm) // 属性名必须和元素的ref属性值一致
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const orderSourceMap = {
|
||||
1: '微信小程序',
|
||||
2: 'APP',
|
||||
3: 'PC'
|
||||
}
|
||||
1: "微信小程序",
|
||||
2: "APP",
|
||||
3: "PC",
|
||||
};
|
||||
|
||||
const orderStatusMap = {
|
||||
101: '待付款',
|
||||
102: '用户取消',
|
||||
103: '系统取消',
|
||||
201: '已付款',
|
||||
202: '申请退款',
|
||||
203: '已退款',
|
||||
301: '待发货',
|
||||
401: '已发货',
|
||||
501: '用户收货',
|
||||
502: '系统收货',
|
||||
901: '已完成'
|
||||
}
|
||||
101: "待付款",
|
||||
102: "用户取消",
|
||||
103: "系统取消",
|
||||
201: "已付款",
|
||||
202: "申请退款",
|
||||
203: "已退款",
|
||||
301: "待发货",
|
||||
401: "已发货",
|
||||
501: "用户收货",
|
||||
502: "系统收货",
|
||||
901: "已完成",
|
||||
};
|
||||
|
||||
const payTypeMap = {
|
||||
1: '支付宝',
|
||||
2: '微信',
|
||||
3: '会员余额'
|
||||
}
|
||||
|
||||
1: "支付宝",
|
||||
2: "微信",
|
||||
3: "会员余额",
|
||||
};
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
@@ -170,15 +160,13 @@ const state = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
orderSn: undefined,
|
||||
status:undefined
|
||||
},
|
||||
pageList: [],
|
||||
} as OrderQueryParam,
|
||||
orderList: [] as Order[],
|
||||
total: 0,
|
||||
dialog: {
|
||||
title: '订单详情',
|
||||
visible: false
|
||||
},
|
||||
title: "订单详情",
|
||||
visible: false,
|
||||
} as Dialog,
|
||||
dialogVisible: false,
|
||||
orderDetail: {
|
||||
order: {
|
||||
@@ -193,57 +181,60 @@ const state = reactive({
|
||||
gmtPay: undefined,
|
||||
integralPrice: undefined,
|
||||
payChannel: undefined,
|
||||
skuPrice : undefined,
|
||||
skuPrice: undefined,
|
||||
couponPrice: undefined,
|
||||
freightPrice: undefined,
|
||||
orderPrice : undefined
|
||||
orderPrice: undefined,
|
||||
},
|
||||
member: {},
|
||||
orderItems: []
|
||||
orderItems: [],
|
||||
},
|
||||
orderSourceMap,
|
||||
orderStatusMap,
|
||||
payTypeMap
|
||||
})
|
||||
payTypeMap,
|
||||
});
|
||||
|
||||
const {loading, single, multiple, queryParams, pageList, total, dialog,dateRange, orderDetail} = toRefs(state)
|
||||
const {
|
||||
loading,
|
||||
single,
|
||||
multiple,
|
||||
queryParams,
|
||||
orderList,
|
||||
total,
|
||||
dialog,
|
||||
dateRange,
|
||||
orderDetail,
|
||||
} = toRefs(state);
|
||||
|
||||
function handleQuery() {
|
||||
state.loading = true
|
||||
listOrdersWithPage(state.queryParams).then(response => {
|
||||
const {data, total} = response as any
|
||||
state.pageList = data
|
||||
state.total = total
|
||||
state.loading = false
|
||||
})
|
||||
state.loading = true;
|
||||
listOrderPages(state.queryParams).then(({ data }) => {
|
||||
state.orderList = data.list;
|
||||
state.total = data.total;
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
state.queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
orderSn: undefined,
|
||||
status: undefined
|
||||
}
|
||||
handleQuery()
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function viewDetail(row: any) {
|
||||
state.dialog.visible = true
|
||||
getOrderDetail(row.id).then(response => {
|
||||
state.orderDetail = response.data
|
||||
})
|
||||
state.dialog.visible = true;
|
||||
getOrderDetail(row.id).then((response: any) => {
|
||||
state.orderDetail = response.data;
|
||||
});
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
state.dialog.visible = false
|
||||
state.dialog.visible = false;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery()
|
||||
})
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,85 +1,73 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form
|
||||
ref="queryFormRef"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
>
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="danger" :icon='Delete' click="handleDelete" :disabled="multiple">删除</el-button>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
click="handleDelete"
|
||||
:disabled="multiple"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="品牌名称"/>
|
||||
<el-input v-model="queryParams.name" placeholder="品牌名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button :icon="Refresh" @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table
|
||||
ref="dataTable"
|
||||
v-loading="loading"
|
||||
:data="pageList"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick"
|
||||
border
|
||||
v-loading="loading"
|
||||
:data="brandList"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick"
|
||||
border
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
min-width="5%"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="品牌名称"
|
||||
min-width="10"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="logoUrl"
|
||||
label="LOGO"
|
||||
min-width="10"
|
||||
>
|
||||
<el-table-column type="selection" min-width="5%" />
|
||||
<el-table-column prop="name" label="品牌名称" min-width="10" />
|
||||
<el-table-column prop="logoUrl" label="LOGO" min-width="10">
|
||||
<template #default="scope">
|
||||
<el-popover
|
||||
placement="right"
|
||||
:width="400"
|
||||
trigger="hover">
|
||||
<img :src="scope.row.logoUrl" width="400" height="400"/>
|
||||
<el-popover placement="right" :width="400" trigger="hover">
|
||||
<img :src="scope.row.logoUrl" width="400" height="400" />
|
||||
<template #reference>
|
||||
<img :src="scope.row.logoUrl" style="max-height: 60px;max-width: 60px"/>
|
||||
<img
|
||||
:src="scope.row.logoUrl"
|
||||
style="max-height: 60px; max-width: 60px"
|
||||
/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="sort"
|
||||
label="排序"
|
||||
min-width="10"
|
||||
/>
|
||||
<el-table-column prop="sort" label="排序" min-width="10" />
|
||||
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="150">
|
||||
<el-table-column label="操作" width="150">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="handleUpdate(scope.row)"
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
circle
|
||||
plain
|
||||
@click="handleUpdate(scope.row)"
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
circle
|
||||
plain
|
||||
/>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
circle
|
||||
plain
|
||||
@click="handleDelete(scope.row)"
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
circle
|
||||
plain
|
||||
@click="handleDelete(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -87,36 +75,36 @@
|
||||
|
||||
<!-- 分页工具条 -->
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
/>
|
||||
|
||||
<!-- 表单弹窗 -->
|
||||
<el-dialog
|
||||
:title="dialog.title"
|
||||
v-model="dialog.visible"
|
||||
top="5vh"
|
||||
width="600px"
|
||||
:title="dialog.title"
|
||||
v-model="dialog.visible"
|
||||
top="5vh"
|
||||
width="600px"
|
||||
>
|
||||
<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="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 label="LOGO" prop="logoUrl">
|
||||
<single-upload v-model="formData.logoUrl"/>
|
||||
<single-upload v-model="formData.logoUrl" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input v-model="formData.sort"/>
|
||||
<el-input v-model="formData.sort" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -131,15 +119,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {listBrandsWithPage, getBrandDetail, updateBrand, addBrand, deleteBrands} from '@/api/pms/brand'
|
||||
import SingleUpload from "@/components/Upload/SingleUpload.vue"
|
||||
import {onMounted, reactive, ref, toRefs, unref} from "vue";
|
||||
import {ElForm, ElTable, ElMessage, ElMessageBox} from "element-plus";
|
||||
import {Search, Plus, Edit, Refresh, Delete} from '@element-plus/icons-vue'
|
||||
import { onMounted, reactive, ref, toRefs, unref } from "vue";
|
||||
import { ElForm, ElTable, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
import { BrandFormData, BrandItem, BrandQueryParam, Dialog } from "@/types";
|
||||
import {
|
||||
listBrandPages,
|
||||
getBrandFormDetail,
|
||||
updateBrand,
|
||||
addBrand,
|
||||
deleteBrands,
|
||||
} from "@/api/pms/brand";
|
||||
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
||||
|
||||
const dataTableRef = ref(ElTable)
|
||||
const queryFormRef = ref(ElForm) // 属性名必须和元素的ref属性值一致
|
||||
const dataFormRef = ref(ElForm) // 属性名必须和元素的ref属性值一致
|
||||
const queryFormRef = ref(ElForm); // 属性名必须和元素的ref属性值一致
|
||||
const dataFormRef = ref(ElForm); // 属性名必须和元素的ref属性值一致
|
||||
|
||||
const state = reactive({
|
||||
loading: true,
|
||||
@@ -152,130 +146,124 @@ const state = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined
|
||||
},
|
||||
pageList: [],
|
||||
} as BrandQueryParam,
|
||||
brandList: [] as BrandItem[],
|
||||
total: 0,
|
||||
dialog: {
|
||||
title: '',
|
||||
visible: false
|
||||
},
|
||||
formData: {
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
logoUrl: undefined,
|
||||
sort: 1
|
||||
},
|
||||
dialog: {} as Dialog,
|
||||
formData: { sort: 1 } as BrandFormData,
|
||||
rules: {
|
||||
name: [{
|
||||
required: true, message: '请输入品牌名称', trigger: 'blur'
|
||||
}]
|
||||
}
|
||||
})
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入品牌名称",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const {loading, single, multiple, queryParams, pageList, total, dialog, formData, rules} = toRefs(state)
|
||||
const {
|
||||
loading,
|
||||
single,
|
||||
multiple,
|
||||
queryParams,
|
||||
brandList,
|
||||
total,
|
||||
dialog,
|
||||
formData,
|
||||
rules,
|
||||
} = toRefs(state);
|
||||
|
||||
function handleQuery() {
|
||||
state.loading = true
|
||||
listBrandsWithPage(state.queryParams).then(response => {
|
||||
const {data, total} = response as any
|
||||
state.pageList = data
|
||||
state.total = total
|
||||
state.loading = false
|
||||
})
|
||||
state.loading = true;
|
||||
listBrandPages(state.queryParams).then(({ data }) => {
|
||||
state.brandList = data.list;
|
||||
state.total = data.total;
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
const dataTable = unref(dataTableRef)
|
||||
dataTable.resetFields()
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
function handleRowClick(row: any) {
|
||||
const dataTable = unref(dataTableRef)
|
||||
dataTable.toggleRowSelection(row);
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection: any) {
|
||||
state.ids = selection.map((item: any) => item.id)
|
||||
state.single = selection.length !== 1
|
||||
state.multiple = !selection.length
|
||||
state.ids = selection.map((item: any) => item.id);
|
||||
state.single = selection.length !== 1;
|
||||
state.multiple = !selection.length;
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
state.dialog = {
|
||||
title: '添加品牌',
|
||||
visible: true
|
||||
}
|
||||
title: "添加品牌",
|
||||
visible: true,
|
||||
};
|
||||
}
|
||||
|
||||
function handleUpdate(row: any) {
|
||||
state.dialog = {
|
||||
title: '修改品牌',
|
||||
title: "修改品牌",
|
||||
visible: true,
|
||||
}
|
||||
const advertId = row.id || state.ids
|
||||
getBrandDetail(advertId).then((response) => {
|
||||
state.formData = response.data
|
||||
})
|
||||
};
|
||||
const brandId = row.id || state.ids;
|
||||
getBrandFormDetail(brandId).then(({ data }) => {
|
||||
state.formData = data;
|
||||
});
|
||||
}
|
||||
|
||||
function submitForm() {
|
||||
const dataForm = unref(dataFormRef)
|
||||
dataForm.validate((valid: any) => {
|
||||
if (valid) {
|
||||
dataFormRef.value.validate((isValid: boolean) => {
|
||||
if (isValid) {
|
||||
if (state.formData.id) {
|
||||
updateBrand(state.formData.id as any, state.formData).then(response => {
|
||||
ElMessage.success('修改成功')
|
||||
state.dialog.visible = false
|
||||
resetForm()
|
||||
handleQuery()
|
||||
})
|
||||
updateBrand(state.formData.id, state.formData).then((response) => {
|
||||
ElMessage.success("修改成功");
|
||||
cancel();
|
||||
handleQuery();
|
||||
});
|
||||
} else {
|
||||
addBrand(state.formData).then(response => {
|
||||
ElMessage.success('新增成功')
|
||||
state.dialog.visible = false
|
||||
resetForm()
|
||||
handleQuery()
|
||||
})
|
||||
addBrand(state.formData).then((response) => {
|
||||
ElMessage.success("新增成功");
|
||||
cancel();
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置表单
|
||||
*/
|
||||
function resetForm() {
|
||||
const dataForm = unref(dataFormRef)
|
||||
dataForm.resetFields()
|
||||
state.formData.id = undefined;
|
||||
dataFormRef.value.resetFields();
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
state.dialog.visible = false
|
||||
resetForm()
|
||||
state.dialog.visible = false;
|
||||
resetForm();
|
||||
}
|
||||
|
||||
function handleDelete(row: any) {
|
||||
const ids = [row.id || state.ids].join(',')
|
||||
ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteBrands(ids).then(() => {
|
||||
ElMessage.success('删除成功')
|
||||
handleQuery()
|
||||
const ids = [row.id || state.ids].join(",");
|
||||
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
deleteBrands(ids).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
handleQuery();
|
||||
});
|
||||
})
|
||||
}).catch(() =>
|
||||
ElMessage.info('已取消删除')
|
||||
)
|
||||
.catch(() => ElMessage.info("已取消删除"));
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery()
|
||||
})
|
||||
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -5,35 +5,35 @@
|
||||
<template #header>
|
||||
<span>商品属性</span>
|
||||
<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>
|
||||
</template>
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:model="modelValue"
|
||||
:rules="rules"
|
||||
size="small"
|
||||
:inline="true"
|
||||
ref="dataForm"
|
||||
:model="modelValue"
|
||||
:rules="rules"
|
||||
size="small"
|
||||
:inline="true"
|
||||
>
|
||||
<el-table
|
||||
:data="modelValue.attrList"
|
||||
size="small"
|
||||
highlight-current-row
|
||||
border
|
||||
:data="modelValue.attrList"
|
||||
size="small"
|
||||
highlight-current-row
|
||||
border
|
||||
>
|
||||
<el-table-column property="name" label="属性名称">
|
||||
<template #default="scope">
|
||||
<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>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -41,10 +41,10 @@
|
||||
<el-table-column property="value" label="属性值">
|
||||
<template #default="scope">
|
||||
<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>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -53,11 +53,13 @@
|
||||
<template #default="scope">
|
||||
<el-form-item>
|
||||
<el-button
|
||||
v-if="scope.$index>0"
|
||||
type="danger"
|
||||
icon="Minus"
|
||||
circle
|
||||
@click="handleRemove(scope.$index)"
|
||||
v-if="scope.$index > 0"
|
||||
type="danger"
|
||||
:icon="Minus"
|
||||
size="small"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleRemove(scope.$index)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
@@ -65,103 +67,99 @@
|
||||
</el-table>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
<div class="component-container__footer">
|
||||
<el-button @click="handlePrev">上一步,填写商品信息</el-button>
|
||||
<el-button type="primary" @click="handleNext">下一步,设置商品库存</el-button>
|
||||
<el-button type="primary" @click="handleNext"
|
||||
>下一步,设置商品库存</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { listAttributes } from "@/api/pms/attribute";
|
||||
import { computed, nextTick, reactive, ref, toRefs, unref, watch } from "vue";
|
||||
import { ElForm } from "element-plus";
|
||||
import { Plus, Minus } from "@element-plus/icons-vue";
|
||||
|
||||
import {listAttributes} from "@/api/pms/attribute";
|
||||
import {computed, nextTick, reactive, ref, toRefs, unref, watch} from "vue";
|
||||
import {ElForm} from "element-plus";
|
||||
import {Minus, Plus} from '@element-plus/icons-vue'
|
||||
|
||||
const emit = defineEmits(['prev', 'next'])
|
||||
const dataForm = ref(ElForm)
|
||||
const emit = defineEmits(["prev", "next"]);
|
||||
const dataForm = ref(ElForm);
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
default: {},
|
||||
},
|
||||
});
|
||||
|
||||
const categoryId = computed(() => props.modelValue.categoryId);
|
||||
|
||||
watch(categoryId, (newVal) => {
|
||||
// 商品编辑不加载分类下的属性
|
||||
const spuId = props.modelValue.id
|
||||
if (spuId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 商品新增加载默认分类下的属性
|
||||
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,
|
||||
deep: true
|
||||
watch(
|
||||
categoryId,
|
||||
(newVal) => {
|
||||
// 商品编辑不加载分类下的属性
|
||||
const spuId = props.modelValue.id;
|
||||
if (spuId) {
|
||||
return false;
|
||||
}
|
||||
)
|
||||
|
||||
// 商品新增加载默认分类下的属性
|
||||
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,
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
const state = reactive({
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: '请填写属性名称', trigger: 'blur'}
|
||||
],
|
||||
value: [
|
||||
{required: true, message: '请填写属性值', trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
})
|
||||
name: [{ required: true, message: "请填写属性名称", trigger: "blur" }],
|
||||
value: [{ required: true, message: "请填写属性值", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const {rules} = toRefs(state)
|
||||
const { rules } = toRefs(state);
|
||||
|
||||
function handleAdd() {
|
||||
props.modelValue.attrList.push({})
|
||||
props.modelValue.attrList.push({});
|
||||
}
|
||||
|
||||
function handleRemove(index: number) {
|
||||
props.modelValue.attrList.splice(index, 1)
|
||||
props.modelValue.attrList.splice(index, 1);
|
||||
}
|
||||
|
||||
function handlePrev() {
|
||||
emit('prev')
|
||||
emit("prev");
|
||||
}
|
||||
|
||||
function handleNext() {
|
||||
const form = unref(dataForm)
|
||||
const form = unref(dataForm);
|
||||
form.validate((valid: any) => {
|
||||
if (valid) {
|
||||
emit('next')
|
||||
emit("next");
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.component-container {
|
||||
&__main {
|
||||
margin: 20px auto
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
|
||||
@@ -2,131 +2,148 @@
|
||||
<div class="component-container">
|
||||
<div class="component-container__main">
|
||||
<el-form
|
||||
ref="dataFormRef"
|
||||
:rules="rules"
|
||||
:model="modelValue"
|
||||
label-width="120px"
|
||||
ref="dataFormRef"
|
||||
:rules="rules"
|
||||
:model="modelValue"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-form-item label="商品品牌" prop="brandId">
|
||||
<el-select
|
||||
v-model="modelValue.brandId"
|
||||
style="width:400px"
|
||||
clearable
|
||||
v-model="modelValue.brandId"
|
||||
style="width: 400px"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in brandOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
v-for="item in brandOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品名称" prop="name">
|
||||
<el-input style="width: 400px" v-model="modelValue.name"/>
|
||||
<el-input style="width: 400px" v-model="modelValue.name" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="原价" prop="originPrice">
|
||||
<el-input style="width: 400px" v-model="modelValue.originPrice"/>
|
||||
<el-input style="width: 400px" v-model="modelValue.originPrice" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="现价" prop="price">
|
||||
<el-input style="width: 400px" v-model="modelValue.price"/>
|
||||
<el-input style="width: 400px" v-model="modelValue.price" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品简介">
|
||||
<el-input type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" v-model="modelValue.description"/>
|
||||
<el-input
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 3, maxRows: 6 }"
|
||||
v-model="modelValue.description"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品相册">
|
||||
<el-card v-for="(item,index) in pictures" style="width: 170px;display: inline-block;margin-left: 10px"
|
||||
:body-style="{ padding: '10px' }">
|
||||
<el-card
|
||||
v-for="(item, index) in pictures"
|
||||
:key="index"
|
||||
style="width: 170px; display: inline-block; margin-left: 10px;text-align:center"
|
||||
:body-style="{ padding: '10px' }"
|
||||
>
|
||||
<single-upload v-model="item.url" :show-close="true" />
|
||||
|
||||
<single-upload v-model="item.url"/>
|
||||
|
||||
<div class="bottom" v-if="item.url">
|
||||
<el-button type="text" 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>
|
||||
<el-button type="text" class="button" @click="removePicture(index)">删除图片</el-button>
|
||||
<div v-if="item.url">
|
||||
<el-button
|
||||
type="text"
|
||||
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 class="bottom" v-else>
|
||||
<div v-else>
|
||||
<!-- 占位 -->
|
||||
<el-button type="text"/>
|
||||
<el-button type="text" />
|
||||
</div>
|
||||
</el-card>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品详情" prop="detail">
|
||||
<editor v-model="modelValue.detail" style="height: 600px"/>
|
||||
<editor v-model="modelValue.detail" style="height: 600px" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="component-container__footer">
|
||||
<el-button @click="handlePrev">上一步,选择商品分类</el-button>
|
||||
<el-button type="primary" @click="handleNext">下一步,设置商品属性</el-button>
|
||||
<el-button type="primary" @click="handleNext"
|
||||
>下一步,设置商品属性</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import {onMounted, reactive, ref, toRefs, unref} from "vue"
|
||||
import {ElForm} from "element-plus"
|
||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||
import { ElForm } from "element-plus";
|
||||
|
||||
// API 依赖
|
||||
import {listBrands} from "@/api/pms/brand"
|
||||
import { listBrands } from "@/api/pms/brand";
|
||||
|
||||
// 自定义组件依赖
|
||||
import SingleUpload from '@/components/Upload/SingleUpload.vue'
|
||||
import Editor from '@/components/WangEditor/index.vue'
|
||||
import Editor from "@/components/WangEditor/index.vue";
|
||||
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
||||
|
||||
const emit = defineEmits(['prev', 'next'])
|
||||
const dataFormRef = ref(ElForm)
|
||||
const emit = defineEmits(["prev", "next"]);
|
||||
const dataFormRef = ref(ElForm);
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
default: {},
|
||||
},
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
brandOptions: [] as Array<any>,
|
||||
// 商品图册
|
||||
pictures: [
|
||||
{url: undefined, main: true}, // main = true 代表主图,可切换
|
||||
{url: undefined, main: false},
|
||||
{url: undefined, main: false},
|
||||
{url: undefined, main: false},
|
||||
{url: undefined, main: false}
|
||||
{ url: undefined, main: true }, // main = true 代表主图,可切换
|
||||
{ url: undefined, main: false },
|
||||
{ url: undefined, main: false },
|
||||
{ url: undefined, main: false },
|
||||
{ url: undefined, main: false },
|
||||
] as Array<any>,
|
||||
rules: {
|
||||
name: [{required: true, message: '请填写商品名称', trigger: 'blur'}],
|
||||
originPrice: [{required: true, message: '请填写原价', trigger: 'blur'}],
|
||||
price: [{required: true, message: '请填写现价', trigger: 'blur'}],
|
||||
brandId: [{required: true, message: '请选择商品品牌', trigger: 'blur'}],
|
||||
}
|
||||
})
|
||||
name: [{ required: true, message: "请填写商品名称", trigger: "blur" }],
|
||||
originPrice: [{ required: true, message: "请填写原价", trigger: "blur" }],
|
||||
price: [{ required: true, message: "请填写现价", trigger: "blur" }],
|
||||
brandId: [{ required: true, message: "请选择商品品牌", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const {brandOptions, pictures, rules} = toRefs(state)
|
||||
const { brandOptions, pictures, rules } = toRefs(state);
|
||||
|
||||
function loadData() {
|
||||
listBrands({}).then(response => {
|
||||
state.brandOptions = response.data
|
||||
})
|
||||
const goodsInfo = props.modelValue
|
||||
console.log('商品信息', goodsInfo)
|
||||
const goodsId = goodsInfo.id
|
||||
listBrands().then(({data}) => {
|
||||
state.brandOptions = data;
|
||||
});
|
||||
const goodsInfo = props.modelValue;
|
||||
const goodsId = goodsInfo.id;
|
||||
if (goodsId) {
|
||||
const mainPicUrl = goodsInfo.picUrl
|
||||
const mainPicUrl = goodsInfo.picUrl;
|
||||
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.subPicUrls;
|
||||
if (subPicUrls && subPicUrls.length > 0) {
|
||||
for (let i = 1; i <= subPicUrls.length; i++) {
|
||||
state.pictures[i].url = subPicUrls[i - 1]
|
||||
state.pictures[i].url = subPicUrls[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,63 +151,65 @@ 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}
|
||||
]
|
||||
{ url: undefined, main: true }, // main 代表主图,可以切换
|
||||
{ url: undefined, main: false },
|
||||
{ url: undefined, main: false },
|
||||
{ url: undefined, main: false },
|
||||
{ url: undefined, main: false },
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换主图
|
||||
*/
|
||||
function changeMainPicture(changeIndex: number) {
|
||||
const currMainPicture = JSON.parse(JSON.stringify(state.pictures[0]))
|
||||
const nextMainPicture = JSON.parse(JSON.stringify(state.pictures[changeIndex]))
|
||||
const currMainPicture = JSON.parse(JSON.stringify(state.pictures[0]));
|
||||
const nextMainPicture = JSON.parse(
|
||||
JSON.stringify(state.pictures[changeIndex])
|
||||
);
|
||||
|
||||
state.pictures[0].url = nextMainPicture.url
|
||||
state.pictures[changeIndex].url = currMainPicture.url
|
||||
}
|
||||
|
||||
function removePicture(index: number) {
|
||||
state.pictures[index].url = undefined
|
||||
state.pictures[0].url = nextMainPicture.url;
|
||||
state.pictures[changeIndex].url = currMainPicture.url;
|
||||
}
|
||||
|
||||
function handlePrev() {
|
||||
emit('prev')
|
||||
emit("prev");
|
||||
}
|
||||
|
||||
function handleNext() {
|
||||
dataFormRef.value.validate((valid: any) => {
|
||||
if (valid) {
|
||||
// 商品图片
|
||||
const mainPicUrl = state.pictures.filter(item => item.main == true && item.url).map(item => item.url)
|
||||
const mainPicUrl = state.pictures
|
||||
.filter((item) => item.main == true && item.url)
|
||||
.map((item) => item.url);
|
||||
if (mainPicUrl && mainPicUrl.length > 0) {
|
||||
props.modelValue.picUrl = mainPicUrl[0]
|
||||
props.modelValue.picUrl = mainPicUrl[0];
|
||||
}
|
||||
const subPicUrl = state.pictures.filter(item => item.main == false && item.url).map(item => item.url)
|
||||
const subPicUrl = state.pictures
|
||||
.filter((item) => item.main == false && item.url)
|
||||
.map((item) => item.url);
|
||||
if (subPicUrl && subPicUrl.length > 0) {
|
||||
props.modelValue.subPicUrls = subPicUrl
|
||||
props.modelValue.subPicUrls = subPicUrl;
|
||||
}
|
||||
emit('next')
|
||||
emit("next");
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.component-container {
|
||||
&__main {
|
||||
margin: 20px auto;
|
||||
|
||||
.button {
|
||||
margin-left: 10px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +217,7 @@ onMounted(() => {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,44 +5,44 @@
|
||||
<template #header>
|
||||
<span>商品规格</span>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
<el-form
|
||||
ref="specFormRef"
|
||||
:model="specForm"
|
||||
:inline="true"
|
||||
size="small"
|
||||
ref="specFormRef"
|
||||
:model="specForm"
|
||||
:inline="true"
|
||||
size="small"
|
||||
>
|
||||
<el-table
|
||||
ref="specTableRef"
|
||||
:data="specForm.specList"
|
||||
row-key="id"
|
||||
size="small"
|
||||
ref="specTableRef"
|
||||
:data="specForm.specList"
|
||||
row-key="id"
|
||||
size="small"
|
||||
>
|
||||
<el-table-column align="center" width="50">
|
||||
<template>
|
||||
<svg-icon class="drag-handler" icon-class="drag"/>
|
||||
<svg-icon class="drag-handler" icon-class="drag" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格名" width="200">
|
||||
<template #default="scope">
|
||||
<el-form-item
|
||||
:prop="'specList[' + scope.$index + '].name'"
|
||||
:rules="rules.spec.name"
|
||||
:prop="'specList[' + scope.$index + '].name'"
|
||||
:rules="rules.spec.name"
|
||||
>
|
||||
<el-input
|
||||
type="text"
|
||||
v-model="scope.row.name"
|
||||
size="small"
|
||||
@input="handleSpecChange()"
|
||||
type="text"
|
||||
v-model="scope.row.name"
|
||||
size="small"
|
||||
@input="handleSpecChange()"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
@@ -50,42 +50,49 @@
|
||||
<el-table-column>
|
||||
<template #header>
|
||||
规格值
|
||||
<el-link type="danger" style="font-size:12px" :underline="false">(默认第一条规格包含图片)</el-link>
|
||||
<el-link
|
||||
type="danger"
|
||||
style="font-size: 12px"
|
||||
:underline="false"
|
||||
>(默认第一条规格包含图片)</el-link
|
||||
>
|
||||
</template>
|
||||
|
||||
<template #default="scope">
|
||||
<div v-for="item in scope.row.values"
|
||||
style="margin-right:15px;display: inline-block"
|
||||
<div
|
||||
v-for="item in scope.row.values"
|
||||
:key="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)"
|
||||
size="small"
|
||||
closable
|
||||
:type="colors[scope.$index % colors.length]"
|
||||
@close="handleSpecValueRemove(scope.$index, item.id)"
|
||||
>
|
||||
{{ item.value }}
|
||||
</el-tag>
|
||||
<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>
|
||||
|
||||
<el-input
|
||||
v-if="tagInputs.length>0 &&tagInputs[scope.$index].visible"
|
||||
v-model="tagInputs[scope.$index].value"
|
||||
@keyup.enter.native="handleSpecValueInput(scope.$index)"
|
||||
@blur="handleSpecValueInput(scope.$index)"
|
||||
style="width: 80px;vertical-align: top"
|
||||
size="small"
|
||||
v-if="tagInputs.length > 0 && tagInputs[scope.$index].visible"
|
||||
v-model="tagInputs[scope.$index].value"
|
||||
@keyup.enter="handleSpecValueInput(scope.$index)"
|
||||
@blur="handleSpecValueInput(scope.$index)"
|
||||
style="width: 80px; vertical-align: top"
|
||||
size="small"
|
||||
/>
|
||||
<el-button
|
||||
v-else
|
||||
@click="handleSpecValueAdd(scope.$index)"
|
||||
:icon="Plus"
|
||||
style="vertical-align: top"
|
||||
size="small"
|
||||
v-else
|
||||
@click="handleSpecValueAdd(scope.$index)"
|
||||
:icon="Plus"
|
||||
style="vertical-align: top"
|
||||
size="small"
|
||||
>
|
||||
添加规格值
|
||||
</el-button>
|
||||
@@ -95,12 +102,13 @@
|
||||
<el-table-column width="60" label="操作">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Minus"
|
||||
size="small"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleSpecRemove(scope.$index)"/>
|
||||
type="danger"
|
||||
:icon="Minus"
|
||||
size="small"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleSpecRemove(scope.$index)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -111,56 +119,56 @@
|
||||
<template #header>
|
||||
<span>商品库存</span>
|
||||
</template>
|
||||
<el-form
|
||||
ref="skuFormRef"
|
||||
:model="skuForm"
|
||||
size="small"
|
||||
:inline="true"
|
||||
>
|
||||
<el-form ref="skuFormRef" :model="skuForm" size="small" :inline="true">
|
||||
<el-table
|
||||
:data="skuForm.skuList"
|
||||
:span-method="objectSpanMethod"
|
||||
highlight-current-row
|
||||
size="small"
|
||||
border
|
||||
:data="skuForm.skuList"
|
||||
:span-method="objectSpanMethod"
|
||||
highlight-current-row
|
||||
size="small"
|
||||
border
|
||||
>
|
||||
|
||||
<el-table-column
|
||||
v-for="(title,index) in specTitles"
|
||||
align="center"
|
||||
:prop="'specValue'+(index+1)"
|
||||
:label="title">
|
||||
v-for="(title, index) in specTitles"
|
||||
:key="index"
|
||||
align="center"
|
||||
:prop="'specValue' + (index + 1)"
|
||||
:label="title"
|
||||
>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="商品编码"
|
||||
align="center"
|
||||
>
|
||||
<el-table-column label="商品编码" align="center">
|
||||
<template #default="scope">
|
||||
<el-form-item :prop="'skuList['+scope.$index+'].skuSn'" :rules="rules.sku.skuSn">
|
||||
<el-input v-model="scope.row.skuSn"/>
|
||||
<el-form-item
|
||||
:prop="'skuList[' + scope.$index + '].skuSn'"
|
||||
:rules="rules.sku.skuSn"
|
||||
>
|
||||
<el-input v-model="scope.row.skuSn" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="价格" align="center">
|
||||
<template #default="scope">
|
||||
<el-form-item :prop="'skuList['+scope.$index+'].price'" :rules="rules.sku.price">
|
||||
<el-input v-model="scope.row.price"/>
|
||||
<el-form-item
|
||||
:prop="'skuList[' + scope.$index + '].price'"
|
||||
:rules="rules.sku.price"
|
||||
>
|
||||
<el-input v-model="scope.row.price" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="库存" align="center">
|
||||
<template #default="scope">
|
||||
<el-form-item :prop="'skuList['+scope.$index+'].stockNum'" :rules="rules.sku.stockNum">
|
||||
<el-input v-model="scope.row.stockNum"/>
|
||||
<el-form-item
|
||||
:prop="'skuList[' + scope.$index + '].stockNum'"
|
||||
:rules="rules.sku.stockNum"
|
||||
>
|
||||
<el-input v-model="scope.row.stockNum" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -168,144 +176,159 @@
|
||||
<el-button @click="handlePrev">上一步,设置商品属性</el-button>
|
||||
<el-button type="primary" @click="submitForm">提交</el-button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {computed, getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs, unref, watch} from "vue";
|
||||
import {useRouter} from "vue-router";
|
||||
import {Plus, Minus} from '@element-plus/icons-vue'
|
||||
import {ElNotification, ElMessage, ElTable, ElForm} from "element-plus"
|
||||
import {
|
||||
computed,
|
||||
getCurrentInstance,
|
||||
nextTick,
|
||||
onMounted,
|
||||
reactive,
|
||||
ref,
|
||||
toRefs,
|
||||
unref,
|
||||
watch,
|
||||
} from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { Plus, Minus } from "@element-plus/icons-vue";
|
||||
import { ElNotification, ElMessage, ElTable, ElForm } from "element-plus";
|
||||
|
||||
// API 引用
|
||||
import {listAttributes} from "@/api/pms/attribute";
|
||||
import {addGoods, updateGoods} from "@/api/pms/goods";
|
||||
import { listAttributes } from "@/api/pms/attribute";
|
||||
import { addGoods, updateGoods } from "@/api/pms/goods";
|
||||
|
||||
// 自定义组件引用
|
||||
import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||
import SingleUpload from '@/components/Upload/SingleUpload.vue'
|
||||
import SvgIcon from "@/components/SvgIcon/index.vue";
|
||||
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
||||
// import Sortable from 'sortablejs'
|
||||
|
||||
const categoryId = computed(() => props.modelValue.categoryId);
|
||||
const emit = defineEmits(['prev', 'next'])
|
||||
const emit = defineEmits(["prev", "next"]);
|
||||
|
||||
const proxy = getCurrentInstance()
|
||||
const router = useRouter()
|
||||
const proxy = getCurrentInstance();
|
||||
const router = useRouter();
|
||||
|
||||
const specTableRef = ref(ElTable)
|
||||
const specFormRef = ref(ElForm)
|
||||
const skuFormRef = ref(ElForm)
|
||||
const specTableRef = ref(ElTable);
|
||||
const specFormRef = ref(ElForm);
|
||||
const skuFormRef = ref(ElForm);
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
|
||||
default: {},
|
||||
},
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
specForm: {
|
||||
specList: []
|
||||
specList: [],
|
||||
},
|
||||
skuForm: {
|
||||
skuList: []
|
||||
skuList: [],
|
||||
},
|
||||
// 规格项表格标题
|
||||
specTitles: [],
|
||||
rules: {
|
||||
spec: {
|
||||
name: [{required: true, message: '请输入规格名称', trigger: 'blur'}],
|
||||
value: [{required: true, message: '请输入规格值', trigger: 'blur'}]
|
||||
name: [{ required: true, message: "请输入规格名称", trigger: "blur" }],
|
||||
value: [{ required: true, message: "请输入规格值", trigger: "blur" }],
|
||||
},
|
||||
sku: {
|
||||
skuSn: [{required: true, message: '请输入商品编号', trigger: 'blur'}],
|
||||
price: [{required: true, message: '请输入商品价格', trigger: 'blur'}],
|
||||
stockNum: [{required: true, message: '请输入商品库存', trigger: 'blur'}],
|
||||
skuSn: [{ required: true, message: "请输入商品编号", trigger: "blur" }],
|
||||
price: [{ required: true, message: "请输入商品价格", trigger: "blur" }],
|
||||
stockNum: [
|
||||
{ required: true, message: "请输入商品库存", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
},
|
||||
colors: ["", "success", "warning", "danger"],
|
||||
tagInputs: [{ value: undefined, visible: false }], // 规格值标签临时值和显隐控制
|
||||
loading: undefined,
|
||||
});
|
||||
|
||||
const { specForm, skuForm, specTitles, rules, colors, tagInputs, loading } =
|
||||
toRefs(state);
|
||||
|
||||
watch(
|
||||
categoryId,
|
||||
(newVal, oldVal) => {
|
||||
// 商品编辑不加载分类下的规格
|
||||
const spuId = props.modelValue.id;
|
||||
if (spuId) {
|
||||
return false;
|
||||
}
|
||||
if (newVal) {
|
||||
// type=1 商品分类下的规格
|
||||
listAttributes({ categoryId: newVal, type: 1 }).then((response) => {
|
||||
const specList = response.data;
|
||||
if (specList && specList.length > 0) {
|
||||
specList.forEach((item) => {
|
||||
state.specForm.specList.push({
|
||||
name: item.name,
|
||||
values: [],
|
||||
});
|
||||
});
|
||||
loadData();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
colors: ['', 'success', 'warning', 'danger'],
|
||||
tagInputs: [{value: undefined, visible: false}], // 规格值标签临时值和显隐控制
|
||||
loading: undefined
|
||||
})
|
||||
|
||||
const {specForm, skuForm, specTitles, rules, colors, tagInputs, loading} = toRefs(state)
|
||||
|
||||
watch(categoryId, (newVal, oldVal) => {
|
||||
// 商品编辑不加载分类下的规格
|
||||
const spuId = props.modelValue.id
|
||||
if (spuId) {
|
||||
return false;
|
||||
}
|
||||
if (newVal) {
|
||||
// type=1 商品分类下的规格
|
||||
listAttributes({categoryId: newVal, type: 1}).then(response => {
|
||||
const specList = response.data
|
||||
if (specList && specList.length > 0) {
|
||||
specList.forEach((item) => {
|
||||
state.specForm.specList.push({
|
||||
name: item.name,
|
||||
values: []
|
||||
})
|
||||
})
|
||||
loadData()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
function loadData() {
|
||||
props.modelValue.specList.forEach((specItem) => {
|
||||
const specIndex = state.specForm.specList.findIndex(item => item.name == specItem.name)
|
||||
const specIndex = state.specForm.specList.findIndex(
|
||||
(item) => item.name == specItem.name
|
||||
);
|
||||
if (specIndex > -1) {
|
||||
state.specForm.specList[specIndex].values.push({
|
||||
id: specItem.id,
|
||||
value: specItem.value,
|
||||
picUrl: specItem.picUrl
|
||||
})
|
||||
picUrl: specItem.picUrl,
|
||||
});
|
||||
} else {
|
||||
state.specForm.specList.push({
|
||||
name: specItem.name,
|
||||
values: [{id: specItem.id, value: specItem.value, picUrl: specItem.picUrl}]
|
||||
})
|
||||
values: [
|
||||
{ id: specItem.id, value: specItem.value, picUrl: specItem.picUrl },
|
||||
],
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// 每个规格项追加一个添加规格值按钮
|
||||
for (let i = 0; i < state.specForm.specList.length; i++) {
|
||||
state.tagInputs.push({'value': undefined, 'visible': false})
|
||||
state.tagInputs.push({ value: undefined, visible: false });
|
||||
}
|
||||
|
||||
// SKU规格ID拼接字符串处理
|
||||
props.modelValue.skuList.forEach((sku) => {
|
||||
sku.specIdArr = sku.specIds.split('_')
|
||||
})
|
||||
sku.specIdArr = sku.specIds.split("_");
|
||||
});
|
||||
|
||||
generateSkuList()
|
||||
generateSkuList();
|
||||
|
||||
handleSpecChange()
|
||||
handleSpecChange();
|
||||
|
||||
handleSpecReorder()
|
||||
handleSpecReorder();
|
||||
|
||||
nextTick(() => {
|
||||
// registerSpecDragSortEvent()
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成SKU列表的title
|
||||
*/
|
||||
function handleSpecChange() {
|
||||
const specList = JSON.parse(JSON.stringify(state.specForm.specList))
|
||||
state.specTitles = specList.map((item) => item.name)
|
||||
const specList = JSON.parse(JSON.stringify(state.specForm.specList));
|
||||
state.specTitles = specList.map((item) => item.name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,8 +336,8 @@ function handleSpecChange() {
|
||||
*/
|
||||
function handleSpecReorder() {
|
||||
state.specForm.specList.forEach((item, index) => {
|
||||
item.index = index
|
||||
})
|
||||
item.index = index;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,56 +372,71 @@ function handleSpecReorder() {
|
||||
* ]
|
||||
*/
|
||||
function generateSkuList() {
|
||||
const specList = JSON.parse(JSON.stringify(state.specForm.specList.filter(item => item.values.length > 0))) // 深拷贝,取有属性的规格项,否则笛卡尔积运算得到的SKU列表值为空
|
||||
const specList = JSON.parse(
|
||||
JSON.stringify(
|
||||
state.specForm.specList.filter((item) => item.values.length > 0)
|
||||
)
|
||||
); // 深拷贝,取有属性的规格项,否则笛卡尔积运算得到的SKU列表值为空
|
||||
// 如果规格为空,生成SKU列表为空
|
||||
if (specList.length === 0) {
|
||||
state.skuForm.skuList = []
|
||||
return
|
||||
state.skuForm.skuList = [];
|
||||
return;
|
||||
}
|
||||
const skuList = specList.reduce((acc, curr) => {
|
||||
let result = []
|
||||
acc.forEach((item) => {
|
||||
// curr => { 'id':1,'name':'颜色','values':[{id:1,value:'白色'},{id:2,value:'黑色'},{id:3,value:'蓝色'}] }
|
||||
curr.values.forEach((v) => { // v=>{id:1,value:'白色'}
|
||||
let temp = Object.assign({}, item)
|
||||
temp.specValues += v.value + '_' // 规格值拼接
|
||||
temp.specIds += v.id + '|' // 规格ID拼接
|
||||
result.push(temp)
|
||||
})
|
||||
})
|
||||
return result
|
||||
}, [{specValues: '', specIds: ''}])
|
||||
const skuList = specList.reduce(
|
||||
(acc, curr) => {
|
||||
let result = [];
|
||||
acc.forEach((item) => {
|
||||
// curr => { 'id':1,'name':'颜色','values':[{id:1,value:'白色'},{id:2,value:'黑色'},{id:3,value:'蓝色'}] }
|
||||
curr.values.forEach((v) => {
|
||||
// v=>{id:1,value:'白色'}
|
||||
let temp = Object.assign({}, item);
|
||||
temp.specValues += v.value + "_"; // 规格值拼接
|
||||
temp.specIds += v.id + "|"; // 规格ID拼接
|
||||
result.push(temp);
|
||||
});
|
||||
});
|
||||
return result;
|
||||
},
|
||||
[{ specValues: "", specIds: "" }]
|
||||
);
|
||||
|
||||
skuList.forEach((item) => {
|
||||
item.specIds = item.specIds.substring(0, item.specIds.length - 1)
|
||||
item.name = item.specValues.substring(0, item.specValues.length - 1).replaceAll('_', ' ')
|
||||
const specIdArr = item.specIds.split('|')
|
||||
const skus = props.modelValue.skuList.filter((sku) =>
|
||||
item.specIds = item.specIds.substring(0, item.specIds.length - 1);
|
||||
item.name = item.specValues
|
||||
.substring(0, item.specValues.length - 1)
|
||||
.replaceAll("_", " ");
|
||||
const specIdArr = item.specIds.split("|");
|
||||
const skus = props.modelValue.skuList.filter(
|
||||
(sku) =>
|
||||
sku.specIdArr.length === specIdArr.length &&
|
||||
sku.specIdArr.every((a) => specIdArr.some((b) => a === b)) &&
|
||||
specIdArr.every((x) => sku.specIdArr.some((y) => x === y))
|
||||
) // 数据库的SKU列表
|
||||
); // 数据库的SKU列表
|
||||
|
||||
if (skus && skus.length > 0) {
|
||||
const sku = skus[0]
|
||||
item.id = sku.id
|
||||
item.skuSn = sku.skuSn
|
||||
item.price = sku.price / 100
|
||||
item.stockNum = sku.stockNum
|
||||
const sku = skus[0];
|
||||
item.id = sku.id;
|
||||
item.skuSn = sku.skuSn;
|
||||
item.price = sku.price / 100;
|
||||
item.stockNum = sku.stockNum;
|
||||
}
|
||||
const specValueArr = item.specValues.substring(0, item.specValues.length - 1).split('_') // ['黑','6+128G','官方标配']
|
||||
const specValueArr = item.specValues
|
||||
.substring(0, item.specValues.length - 1)
|
||||
.split("_"); // ['黑','6+128G','官方标配']
|
||||
specValueArr.forEach((v, i) => {
|
||||
const key = 'specValue' + (i + 1)
|
||||
item[key] = v
|
||||
const key = "specValue" + (i + 1);
|
||||
item[key] = v;
|
||||
if (i == 0 && state.specForm.specList.length > 0) {
|
||||
const valueIndex = state.specForm.specList[0].values.findIndex((specValue) => specValue.value == v)
|
||||
const valueIndex = state.specForm.specList[0].values.findIndex(
|
||||
(specValue) => specValue.value == v
|
||||
);
|
||||
if (valueIndex > -1) {
|
||||
item.picUrl = state.specForm.specList[0].values[valueIndex].picUrl
|
||||
item.picUrl = state.specForm.specList[0].values[valueIndex].picUrl;
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
state.skuForm.skuList = JSON.parse(JSON.stringify(skuList))
|
||||
});
|
||||
});
|
||||
state.skuForm.skuList = JSON.parse(JSON.stringify(skuList));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,12 +444,12 @@ function generateSkuList() {
|
||||
*/
|
||||
function handleSpecAdd() {
|
||||
if (state.specForm.specList.length >= 3) {
|
||||
ElMessage.warning('最多支持3组规格')
|
||||
return
|
||||
ElMessage.warning("最多支持3组规格");
|
||||
return;
|
||||
}
|
||||
state.specForm.specList.push({})
|
||||
state.tagInputs.push({'value': undefined, 'visible': false})
|
||||
handleSpecReorder()
|
||||
state.specForm.specList.push({});
|
||||
state.tagInputs.push({ value: undefined, visible: false });
|
||||
handleSpecReorder();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,11 +457,11 @@ function handleSpecAdd() {
|
||||
* @param index
|
||||
*/
|
||||
function handleSpecRemove(index) {
|
||||
state.specForm.specList.splice(index, 1)
|
||||
state.tagInputs.splice(index, 1)
|
||||
generateSkuList()
|
||||
handleSpecReorder()
|
||||
handleSpecChange()
|
||||
state.specForm.specList.splice(index, 1);
|
||||
state.tagInputs.splice(index, 1);
|
||||
generateSkuList();
|
||||
handleSpecReorder();
|
||||
handleSpecChange();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,7 +470,7 @@ function handleSpecRemove(index) {
|
||||
* @param specIndex
|
||||
*/
|
||||
function handleSpecValueAdd(specIndex) {
|
||||
state.tagInputs[specIndex].visible = true
|
||||
state.tagInputs[specIndex].visible = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,85 +480,96 @@ function handleSpecValueAdd(specIndex) {
|
||||
* @param specValueId
|
||||
*/
|
||||
function handleSpecValueRemove(rowIndex, specValueId) {
|
||||
const specList = JSON.parse(JSON.stringify(state.specForm.specList))
|
||||
const removeIndex = specList[rowIndex].values.map((item) => item.id).indexOf(specValueId)
|
||||
specList[rowIndex].values.splice(removeIndex, 1)
|
||||
state.specForm.specList = specList
|
||||
generateSkuList()
|
||||
handleSpecChange()
|
||||
handleSpecReorder()
|
||||
const specList = JSON.parse(JSON.stringify(state.specForm.specList));
|
||||
const removeIndex = specList[rowIndex].values
|
||||
.map((item) => item.id)
|
||||
.indexOf(specValueId);
|
||||
specList[rowIndex].values.splice(removeIndex, 1);
|
||||
state.specForm.specList = specList;
|
||||
generateSkuList();
|
||||
handleSpecChange();
|
||||
handleSpecReorder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 规格值输入
|
||||
*/
|
||||
function handleSpecValueInput(rowIndex) {
|
||||
const currSpecValue = state.tagInputs[rowIndex].value
|
||||
const specValues = state.specForm.specList[rowIndex].values
|
||||
if (specValues && specValues.length > 0 && specValues.map((item) => item.value).includes(currSpecValue)) {
|
||||
ElMessage.warning("规格值重复,请重新输入")
|
||||
return false
|
||||
const currSpecValue = state.tagInputs[rowIndex].value;
|
||||
const specValues = state.specForm.specList[rowIndex].values;
|
||||
if (
|
||||
specValues &&
|
||||
specValues.length > 0 &&
|
||||
specValues.map((item) => item.value).includes(currSpecValue)
|
||||
) {
|
||||
ElMessage.warning("规格值重复,请重新输入");
|
||||
return false;
|
||||
}
|
||||
if (currSpecValue) {
|
||||
if (specValues && specValues.length > 0) {
|
||||
// 临时规格值ID tid_1_1
|
||||
let maxSpecValueIndex = specValues.filter((item) => item.id.includes('tid_')).map((item) => item.id.split('_')[2]).reduce((acc, curr) => {
|
||||
return acc > curr ? acc : curr
|
||||
}, 0)
|
||||
console.log('maxSpecValueIndex', maxSpecValueIndex)
|
||||
let maxSpecValueIndex = specValues
|
||||
.filter((item) => item.id.includes("tid_"))
|
||||
.map((item) => item.id.split("_")[2])
|
||||
.reduce((acc, curr) => {
|
||||
return acc > curr ? acc : curr;
|
||||
}, 0);
|
||||
console.log("maxSpecValueIndex", maxSpecValueIndex);
|
||||
state.specForm.specList[rowIndex].values[specValues.length] = {
|
||||
'value': currSpecValue,
|
||||
'id': 'tid_' + (rowIndex + 1) + '_' + ++maxSpecValueIndex
|
||||
}
|
||||
value: currSpecValue,
|
||||
id: "tid_" + (rowIndex + 1) + "_" + ++maxSpecValueIndex,
|
||||
};
|
||||
} else {
|
||||
state.specForm.specList[rowIndex].values = [{'value': currSpecValue, 'id': 'tid_' + (rowIndex + 1) + '_1'}]
|
||||
state.specForm.specList[rowIndex].values = [
|
||||
{ value: currSpecValue, id: "tid_" + (rowIndex + 1) + "_1" },
|
||||
];
|
||||
}
|
||||
}
|
||||
state.tagInputs[rowIndex].value = undefined
|
||||
state.tagInputs[rowIndex].visible = false
|
||||
generateSkuList()
|
||||
state.tagInputs[rowIndex].value = undefined;
|
||||
state.tagInputs[rowIndex].visible = false;
|
||||
generateSkuList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 合并规格单元格
|
||||
*
|
||||
* @param cellObj 单元格对象
|
||||
*/
|
||||
|
||||
const objectSpanMethod = ({
|
||||
row,
|
||||
column,
|
||||
rowIndex,
|
||||
columnIndex,
|
||||
}) => {
|
||||
|
||||
let mergeRows = [1, 1, 1] // 分别对应规格1、规格2、规格3列合并的行数
|
||||
const specLen = state.specForm.specList.filter(item => item.values && item.values.length > 0).length
|
||||
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
||||
let mergeRows = [1, 1, 1]; // 分别对应规格1、规格2、规格3列合并的行数
|
||||
const specLen = state.specForm.specList.filter(
|
||||
(item) => item.values && item.values.length > 0
|
||||
).length;
|
||||
if (specLen == 2) {
|
||||
const values_len_2 = state.specForm.specList[1].values ? state.specForm.specList[1].values.length : 1 // 第2个规格项的规格值的数量
|
||||
mergeRows = [values_len_2, 1, 1]
|
||||
const values_len_2 = state.specForm.specList[1].values
|
||||
? state.specForm.specList[1].values.length
|
||||
: 1; // 第2个规格项的规格值的数量
|
||||
mergeRows = [values_len_2, 1, 1];
|
||||
} else if (specLen == 3) {
|
||||
const values_len_2 = state.specForm.specList[1].values ? state.specForm.specList[1].values.length : 1 // 第2个规格项的规格值的数量
|
||||
const values_len_3 = state.specForm.specList[2].values ? state.specForm.specList[2].values.length : 1 // 第3个规格项的规格值的数量
|
||||
mergeRows = [values_len_2 * values_len_3, values_len_3, 1]
|
||||
const values_len_2 = state.specForm.specList[1].values
|
||||
? state.specForm.specList[1].values.length
|
||||
: 1; // 第2个规格项的规格值的数量
|
||||
const values_len_3 = state.specForm.specList[2].values
|
||||
? state.specForm.specList[2].values.length
|
||||
: 1; // 第3个规格项的规格值的数量
|
||||
mergeRows = [values_len_2 * values_len_3, values_len_3, 1];
|
||||
}
|
||||
if (columnIndex == 0) {
|
||||
if (rowIndex % mergeRows[0] === 0) {
|
||||
return [mergeRows[0], 1]// 合并单元格
|
||||
return [mergeRows[0], 1]; // 合并单元格
|
||||
} else {
|
||||
return [0, 0] // 隐藏单元格
|
||||
return [0, 0]; // 隐藏单元格
|
||||
}
|
||||
}
|
||||
if (columnIndex == 1) {
|
||||
if (rowIndex % mergeRows[1] === 0) {
|
||||
return [mergeRows[1], 1]// 合并单元格
|
||||
return [mergeRows[1], 1]; // 合并单元格
|
||||
} else {
|
||||
return [0, 0] // 隐藏单元格
|
||||
return [0, 0]; // 隐藏单元格
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 商品表单提交
|
||||
@@ -528,7 +577,7 @@ const objectSpanMethod = ({
|
||||
function submitForm() {
|
||||
// 判断商品SKU列表是否为空
|
||||
if (!state.skuForm.skuList || state.skuForm.skuList.length === 0) {
|
||||
ElMessage.warning("未添加商品库存")
|
||||
ElMessage.warning("未添加商品库存");
|
||||
return false;
|
||||
}
|
||||
specFormRef.value.validate((specValid) => {
|
||||
@@ -538,96 +587,101 @@ function submitForm() {
|
||||
// openFullScreen()
|
||||
|
||||
// 重组商品的规格和SKU列表
|
||||
let submitsData = Object.assign({}, props.modelValue)
|
||||
delete submitsData.specList
|
||||
delete submitsData.skuList
|
||||
let submitsData = Object.assign({}, props.modelValue);
|
||||
delete submitsData.specList;
|
||||
delete submitsData.skuList;
|
||||
|
||||
let specList = []
|
||||
state.specForm.specList.forEach(item => {
|
||||
let specList = [];
|
||||
state.specForm.specList.forEach((item) => {
|
||||
item.values.forEach((value) => {
|
||||
value.name = item.name
|
||||
})
|
||||
specList = specList.concat(item.values)
|
||||
})
|
||||
submitsData.specList = specList // 规格列表
|
||||
value.name = item.name;
|
||||
});
|
||||
specList = specList.concat(item.values);
|
||||
});
|
||||
submitsData.specList = specList; // 规格列表
|
||||
|
||||
submitsData.price *= 100 // 金额转成分保存至数据库
|
||||
submitsData.originPrice *= 100
|
||||
submitsData.price *= 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) => {
|
||||
item.price *= 100
|
||||
return item
|
||||
})
|
||||
submitsData.skuList = skuList
|
||||
console.log('提交数据', submitsData)
|
||||
const goodsId = props.modelValue.id
|
||||
if (goodsId) { // 编辑商品提交
|
||||
updateGoods(goodsId, submitsData).then((res) => {
|
||||
router.push({path: '/pms/goods'})
|
||||
ElNotification({
|
||||
title: '提示',
|
||||
message: '编辑商品成功',
|
||||
type: 'success',
|
||||
})
|
||||
//closeFullScreen()
|
||||
}, (err) => {
|
||||
//closeFullScreen()
|
||||
}
|
||||
)
|
||||
} else { // 新增商品提交
|
||||
addGoods(submitsData).then(response => {
|
||||
router.push({path: '/pms/goods'})
|
||||
ElNotification({
|
||||
title: '提示',
|
||||
message: '新增商品成功',
|
||||
type: 'success',
|
||||
})
|
||||
// closeFullScreen()
|
||||
}, (err) => {
|
||||
// closeFullScreen()
|
||||
})
|
||||
item.price *= 100;
|
||||
return item;
|
||||
});
|
||||
submitsData.skuList = skuList;
|
||||
console.log("提交数据", submitsData);
|
||||
const goodsId = props.modelValue.id;
|
||||
if (goodsId) {
|
||||
// 编辑商品提交
|
||||
updateGoods(goodsId, submitsData).then(
|
||||
(res) => {
|
||||
router.push({ path: "/pms/goods" });
|
||||
ElNotification({
|
||||
title: "提示",
|
||||
message: "编辑商品成功",
|
||||
type: "success",
|
||||
});
|
||||
//closeFullScreen()
|
||||
},
|
||||
(err) => {
|
||||
//closeFullScreen()
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// 新增商品提交
|
||||
addGoods(submitsData).then(
|
||||
(response) => {
|
||||
router.push({ path: "/pms/goods" });
|
||||
ElNotification({
|
||||
title: "提示",
|
||||
message: "新增商品成功",
|
||||
type: "success",
|
||||
});
|
||||
// closeFullScreen()
|
||||
},
|
||||
(err) => {
|
||||
// closeFullScreen()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function openFullScreen() {
|
||||
state.loading = proxy.$loading({
|
||||
lock: true,
|
||||
text: '商品信息提交中,请等待...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
text: "商品信息提交中,请等待...",
|
||||
spinner: "el-icon-loading",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
});
|
||||
}
|
||||
|
||||
function closeFullScreen() {
|
||||
if (state.loading) {
|
||||
state.loading.close()
|
||||
state.loading.close();
|
||||
}
|
||||
}
|
||||
|
||||
function handlePrev() {
|
||||
emit('prev')
|
||||
emit("prev");
|
||||
}
|
||||
|
||||
function handNext() {
|
||||
emit('next')
|
||||
emit("next");
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.component-container {
|
||||
&__main {
|
||||
margin: 20px auto
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
|
||||
@@ -46,7 +46,7 @@ import GoodsInfo from "./components/GoodsInfo.vue";
|
||||
import GoodsAttribute from "./components/GoodsAttribute.vue";
|
||||
import GoodsStock from "./components/GoodsStock.vue";
|
||||
|
||||
import {getGoodsDetail} from "@/api/pms/goods";
|
||||
import {getGoodsFormDetail} from "@/api/pms/goods";
|
||||
|
||||
export default {
|
||||
name: "goods-detail",
|
||||
@@ -81,7 +81,7 @@ export default {
|
||||
const goodsId = this.$route.query.goodsId
|
||||
console.log('goodsId',goodsId)
|
||||
if (goodsId) {
|
||||
getGoodsDetail(goodsId).then(response => {
|
||||
getGoodsFormDetail(goodsId).then(response => {
|
||||
this.goods = response.data
|
||||
this.goods.originPrice = this.goods.originPrice / 100
|
||||
this.goods.price = this.goods.price / 100
|
||||
|
||||
@@ -1,108 +1,122 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
ref="queryForm"
|
||||
:inline="true"
|
||||
|
||||
>
|
||||
<el-form ref="queryForm" :inline="true">
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">发布商品</el-button>
|
||||
<el-button type="danger" :icon="Delete" @click="handleDelete" :disabled="multiple">删除</el-button>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
||||
>发布商品</el-button
|
||||
>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
@click="handleDelete"
|
||||
:disabled="multiple"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-input v-model="queryParams.name" placeholder="商品名称" clearable></el-input>
|
||||
<el-input
|
||||
v-model="queryParams.name"
|
||||
placeholder="商品名称"
|
||||
clearable
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-cascader
|
||||
v-model="queryParams.categoryId"
|
||||
placeholder="商品分类"
|
||||
:props="{emitPath: false, expandTrigger: 'hover'}"
|
||||
:options="categoryOptions"
|
||||
clearable
|
||||
style="width: 300px"
|
||||
v-model="queryParams.categoryId"
|
||||
placeholder="商品分类"
|
||||
:props="{ emitPath: false, expandTrigger: 'hover' }"
|
||||
:options="categoryOptions"
|
||||
clearable
|
||||
style="width: 300px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">查询</el-button>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
||||
>查询</el-button
|
||||
>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
ref="dataTableRef"
|
||||
:data="pageList"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick"
|
||||
border
|
||||
ref="dataTableRef"
|
||||
v-loading="loading"
|
||||
:data="goodsList"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick"
|
||||
border
|
||||
>
|
||||
<el-table-column type="selection" min-width="5%" center/>
|
||||
<el-table-column type="selection" min-width="5%" center />
|
||||
<el-table-column type="expand" width="120" label="库存信息">
|
||||
|
||||
<template #default="props">
|
||||
<el-table
|
||||
:data="props.row.skuList"
|
||||
border>
|
||||
<el-table-column align="center" label="商品编码" prop="skuSn"/>
|
||||
<el-table-column align="center" label="商品规格" prop="name"/>
|
||||
<el-table :data="props.row.skuList" border>
|
||||
<el-table-column align="center" label="商品编码" prop="skuSn" />
|
||||
<el-table-column align="center" label="商品规格" prop="name" />
|
||||
<el-table-column label="图片" prop="picUrl">
|
||||
<template #default="scope">
|
||||
<img :src="scope.row.picUrl" width="40">
|
||||
<img :src="scope.row.picUrl" width="40" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="现价" prop="price">
|
||||
<template #default="scope">{{ moneyFormatter(scope.row.price) }}</template>
|
||||
<template #default="scope">{{
|
||||
moneyFormatter(scope.row.price)
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="库存" prop="stockNum"/>
|
||||
<el-table-column align="center" label="库存" prop="stockNum" />
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" prop="name" min-width="140"/>
|
||||
<el-table-column label="商品名称" prop="name" min-width="140" />
|
||||
<el-table-column label="商品图片">
|
||||
<template #default="scope">
|
||||
<el-popover
|
||||
placement="right"
|
||||
:width="400"
|
||||
trigger="hover">
|
||||
<img :src="scope.row.picUrl" width="400" height="400"/>
|
||||
<el-popover placement="right" :width="400" trigger="hover">
|
||||
<img :src="scope.row.picUrl" width="400" height="400" />
|
||||
<template #reference>
|
||||
<img :src="scope.row.picUrl" style="max-height: 60px;max-width: 60px"/>
|
||||
<img
|
||||
:src="scope.row.picUrl"
|
||||
style="max-height: 60px; max-width: 60px"
|
||||
/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品类目" prop="categoryName" min-width="100"/>
|
||||
<el-table-column label="商品品牌" prop="brandName" min-width="100"/>
|
||||
<el-table-column label="商品类目" prop="categoryName" min-width="100" />
|
||||
<el-table-column label="商品品牌" prop="brandName" min-width="100" />
|
||||
<el-table-column align="center" label="零售价" prop="originalPrice">
|
||||
<template #default="scope">{{ moneyFormatter(scope.row.originPrice) }}</template>
|
||||
<template #default="scope">{{
|
||||
moneyFormatter(scope.row.originPrice)
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="促销价" prop="price">
|
||||
<template #default="scope">{{ moneyFormatter(scope.row.price) }}</template>
|
||||
<template #default="scope">{{
|
||||
moneyFormatter(scope.row.price)
|
||||
}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="销量" prop="sales" min-width="100"/>
|
||||
<el-table-column label="单位" prop="unit" min-width="100"/>
|
||||
<el-table-column label="描述" prop="description" min-width="100"/>
|
||||
<el-table-column label="销量" prop="sales" min-width="100" />
|
||||
<el-table-column label="单位" prop="unit" min-width="100" />
|
||||
<el-table-column label="描述" prop="description" min-width="100" />
|
||||
<el-table-column label="详情" prop="detail">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="handleGoodsView(scope.row.detail)">查看</el-button>
|
||||
<el-button type="primary" @click="handleGoodsView(scope.row.detail)"
|
||||
>查看</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleUpdate(scope.row)"
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleUpdate(scope.row)"
|
||||
/>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleDelete(scope.row)"
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleDelete(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -110,30 +124,31 @@
|
||||
|
||||
<!-- 分页工具条 -->
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
/>
|
||||
<el-dialog v-model="dialogVisible" title="商品详情">
|
||||
<div class="goods-detail-box" v-html="goodDetail"/>
|
||||
<div class="goods-detail-box" v-html="goodDetail" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {Search, Plus, Edit, Refresh, Delete} from '@element-plus/icons-vue'
|
||||
import {listGoodsWithPage, deleteGoods} from '@/api/pms/goods'
|
||||
import {listCascadeCategories} from '@/api/pms/category'
|
||||
import {reactive, ref, onMounted, toRefs} from 'vue'
|
||||
import {ElTable, ElMessage, ElMessageBox} from 'element-plus'
|
||||
import {getCurrentInstance} from 'vue'
|
||||
import {moneyFormatter} from '@/utils/filter'
|
||||
import {useRouter} from "vue-router"
|
||||
import { reactive, ref, onMounted, toRefs } from "vue";
|
||||
import { ElTable, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const dataTableRef = ref(ElTable)
|
||||
const router=useRouter()
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
import { listGoodsPages, deleteGoods } from "@/api/pms/goods";
|
||||
import { listCascadeCategories } from "@/api/pms/category";
|
||||
import { GoodsItem, GoodsQueryParam } from "@/types";
|
||||
import {moneyFormatter} from '@/utils/filter'
|
||||
|
||||
const dataTableRef = ref(ElTable);
|
||||
const router = useRouter();
|
||||
|
||||
const state = reactive({
|
||||
// 遮罩层
|
||||
@@ -148,15 +163,12 @@ const state = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
categoryId: undefined
|
||||
},
|
||||
pageList: [],
|
||||
} as GoodsQueryParam,
|
||||
goodsList: [] as GoodsItem[],
|
||||
categoryOptions: [],
|
||||
goodDetail: undefined,
|
||||
dialogVisible: false
|
||||
})
|
||||
|
||||
dialogVisible: false,
|
||||
});
|
||||
|
||||
const {
|
||||
loading,
|
||||
@@ -164,22 +176,20 @@ const {
|
||||
single,
|
||||
multiple,
|
||||
queryParams,
|
||||
pageList,
|
||||
goodsList,
|
||||
categoryOptions,
|
||||
goodDetail,
|
||||
total,
|
||||
dialogVisible
|
||||
dialogVisible,
|
||||
} = toRefs(state);
|
||||
|
||||
|
||||
function handleQuery() {
|
||||
state.loading = true
|
||||
listGoodsWithPage(state.queryParams).then(response => {
|
||||
const {data, total} = response as any
|
||||
state.pageList = data
|
||||
state.total = total
|
||||
state.loading = false
|
||||
})
|
||||
state.loading = true;
|
||||
listGoodsPages(state.queryParams).then(({ data }) => {
|
||||
state.goodsList = data.list;
|
||||
state.total = data.total;
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
@@ -187,36 +197,41 @@ function resetQuery() {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
categoryId: undefined
|
||||
}
|
||||
handleQuery()
|
||||
categoryId: undefined,
|
||||
};
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function handleGoodsView(detail: any) {
|
||||
state.goodDetail = detail
|
||||
state.dialogVisible = true
|
||||
state.goodDetail = detail;
|
||||
state.dialogVisible = true;
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
router.push({path: 'goods-detail'})
|
||||
router.push({ path: "goods-detail" });
|
||||
}
|
||||
|
||||
function handleUpdate(row: any) {
|
||||
router.push({path: 'goods-detail', query: {goodsId: row.id, categoryId: row.categoryId}})
|
||||
router.push({
|
||||
path: "goods-detail",
|
||||
query: { goodsId: row.id, categoryId: row.categoryId },
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(row: any) {
|
||||
const ids = row.id || state.ids.join(',')
|
||||
ElMessageBox.confirm('是否确认删除选中的数据项?', "警告", {
|
||||
const ids = row.id || state.ids.join(",");
|
||||
ElMessageBox.confirm("是否确认删除选中的数据项?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(function () {
|
||||
return deleteGoods(ids)
|
||||
}).then(() => {
|
||||
ElMessage.success("删除成功")
|
||||
handleQuery()
|
||||
type: "warning",
|
||||
})
|
||||
.then(function () {
|
||||
return deleteGoods(ids);
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
|
||||
function handleRowClick(row: any) {
|
||||
@@ -224,19 +239,18 @@ function handleRowClick(row: any) {
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection: any) {
|
||||
state.ids = selection.map((item: { id: any }) => item.id)
|
||||
state.single = selection.length != 1
|
||||
state.multiple = !selection.length
|
||||
state.ids = selection.map((item: { id: any }) => item.id);
|
||||
state.single = selection.length != 1;
|
||||
state.multiple = !selection.length;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
listCascadeCategories({}).then(response => {
|
||||
state.categoryOptions = ref(response.data)
|
||||
})
|
||||
handleQuery()
|
||||
})
|
||||
listCascadeCategories({}).then((response) => {
|
||||
state.categoryOptions = ref(response.data);
|
||||
});
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,77 +1,82 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form
|
||||
ref="queryForm"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
>
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
||||
>新增</el-button
|
||||
>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-input
|
||||
v-model="queryParams.title"
|
||||
placeholder="广告标题"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
v-model="queryParams.title"
|
||||
placeholder="广告标题"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table
|
||||
ref="dataTable"
|
||||
v-loading="loading"
|
||||
:data="pageList"
|
||||
@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="index" label="序号" width="80" 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 prop="title" min-width="100" label="广告标题" />
|
||||
<el-table-column label="广告图片" width="100">
|
||||
<template #default="scope">
|
||||
<el-popover
|
||||
placement="right"
|
||||
:width="400"
|
||||
trigger="hover">
|
||||
<img :src="scope.row.picUrl" width="400" height="400"/>
|
||||
<el-popover placement="right" :width="400" trigger="hover">
|
||||
<img :src="scope.row.picUrl" width="400" height="400" />
|
||||
<template #reference>
|
||||
<img :src="scope.row.picUrl" style="max-height: 60px;max-width: 60px"/>
|
||||
<img
|
||||
:src="scope.row.picUrl"
|
||||
style="max-height: 60px; max-width: 60px"
|
||||
/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="beginTime" label="开始时间" width="150"/>
|
||||
<el-table-column prop="endTime" label="结束时间" width="150"/>
|
||||
<el-table-column prop="beginTime" label="开始时间" width="150" />
|
||||
<el-table-column prop="endTime" label="结束时间" width="150" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status===1" type="success" >开启</el-tag>
|
||||
<el-tag v-if="scope.row.status === 1" type="success">开启</el-tag>
|
||||
<el-tag v-else type="info">关闭</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort" label="排序" width="80"/>
|
||||
<el-table-column prop="sort" label="排序" width="80" />
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleUpdate(scope.row)"
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleUpdate(scope.row)"
|
||||
/>
|
||||
<el-button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleDelete(scope.row)"
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
circle
|
||||
plain
|
||||
@click.stop="handleDelete(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -79,49 +84,45 @@
|
||||
|
||||
<!-- 分页工具条 -->
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
v-show="total > 0"
|
||||
: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
|
||||
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-input v-model="formData.title"/>
|
||||
<el-input v-model="formData.title" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="有效期" prop="beginTime">
|
||||
<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
|
||||
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 label="广告图片" prop="picUrl">
|
||||
<single-upload v-model="formData.picUrl"/>
|
||||
<single-upload v-model="formData.picUrl" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input v-model="formData.sort" style="width: 200px"/>
|
||||
<el-input v-model="formData.sort" style="width: 200px" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态" prop="status">
|
||||
@@ -132,11 +133,11 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="跳转链接" prop="url">
|
||||
<el-input v-model="formData.url"/>
|
||||
<el-input v-model="formData.url" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input type="textarea" v-model="formData.remark"/>
|
||||
<el-input type="textarea" v-model="formData.remark" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -146,19 +147,26 @@
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {listAdvertsWithPage, getAdvertDetail, updateAdvert, addAdvert, deleteAdverts} from '@/api/sms/advert'
|
||||
import { onMounted, reactive, ref, toRefs, unref } from "vue";
|
||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
import SingleUpload from "@/components/Upload/SingleUpload.vue";
|
||||
import {onMounted, reactive, ref, toRefs, unref} from "vue";
|
||||
import {ElForm, ElMessage, ElMessageBox} from "element-plus";
|
||||
import {Search, Plus, Edit, Refresh, Delete} from '@element-plus/icons-vue'
|
||||
import {
|
||||
listAdvertPages,
|
||||
getAdvertFormDetail,
|
||||
updateAdvert,
|
||||
addAdvert,
|
||||
deleteAdverts,
|
||||
} from "@/api/sms/advert";
|
||||
import { AdvertFormData, AdvertItem, AdvertQueryParam, Dialog } from "@/types";
|
||||
|
||||
const dataFormRef = ref(ElForm) // 属性名必须和元素的ref属性值一致
|
||||
const queryFormRef = ref(ElForm); // 属性名必须和元素的ref属性值一致
|
||||
const dataFormRef = ref(ElForm); // 属性名必须和元素的ref属性值一致
|
||||
|
||||
const state = reactive({
|
||||
loading: true,
|
||||
@@ -168,150 +176,124 @@ const state = reactive({
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
title: undefined
|
||||
},
|
||||
pageList: [],
|
||||
queryParams: { pageNum: 1, pageSize: 10 } as AdvertQueryParam,
|
||||
advertList: [] as AdvertItem[],
|
||||
total: 0,
|
||||
dialog: {
|
||||
title: '',
|
||||
visible: false
|
||||
},
|
||||
dialog: {} as Dialog,
|
||||
formData: {
|
||||
id: undefined,
|
||||
title: '',
|
||||
picUrl: '',
|
||||
beginTime: undefined,
|
||||
endTime: undefined,
|
||||
status: 1,
|
||||
sort: 100,
|
||||
url: undefined,
|
||||
remark: undefined
|
||||
},
|
||||
} as AdvertFormData,
|
||||
rules: {
|
||||
title: [
|
||||
{required: true, message: '请输入广告名称', trigger: 'blur'}
|
||||
],
|
||||
beginTime: [
|
||||
{required: true, message: '请填写开始时间', trigger: 'blur'}
|
||||
],
|
||||
endTime: [
|
||||
{required: true, message: '请填写结束时间', trigger: 'blur'}
|
||||
],
|
||||
picUrl: [
|
||||
{required: true, message: '请上传广告图片', trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
})
|
||||
title: [{ required: true, message: "请输入广告名称", trigger: "blur" }],
|
||||
beginTime: [{ required: true, message: "请填写开始时间", trigger: "blur" }],
|
||||
endTime: [{ required: true, message: "请填写结束时间", trigger: "blur" }],
|
||||
picUrl: [{ required: true, message: "请上传广告图片", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const {loading, single, multiple, queryParams, pageList, total, dialog, formData, rules} = toRefs(state)
|
||||
const {
|
||||
loading,
|
||||
single,
|
||||
multiple,
|
||||
queryParams,
|
||||
advertList,
|
||||
total,
|
||||
dialog,
|
||||
formData,
|
||||
rules,
|
||||
} = toRefs(state);
|
||||
|
||||
function handleQuery() {
|
||||
state.loading = true
|
||||
listAdvertsWithPage(state.queryParams).then(response => {
|
||||
const {data, total} = response as any
|
||||
state.pageList = data
|
||||
state.total = total
|
||||
state.loading = false
|
||||
})
|
||||
state.loading = true;
|
||||
listAdvertPages(state.queryParams).then(({data}) => {
|
||||
state.advertList = data.list;
|
||||
state.total = data.total;
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
state.queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
title: undefined
|
||||
}
|
||||
handleQuery()
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection: any) {
|
||||
state.ids = selection.map((item: any) => item.id)
|
||||
state.single = selection.length !== 1
|
||||
state.multiple = !selection.length
|
||||
state.ids = selection.map((item: any) => item.id);
|
||||
state.single = selection.length !== 1;
|
||||
state.multiple = !selection.length;
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
resetForm()
|
||||
resetForm();
|
||||
state.dialog = {
|
||||
title: '添加广告',
|
||||
visible: true
|
||||
}
|
||||
title: "添加广告",
|
||||
visible: true,
|
||||
};
|
||||
}
|
||||
|
||||
function handleUpdate(row: any) {
|
||||
resetForm()
|
||||
state.dialog = {
|
||||
title: '修改广告',
|
||||
title: "修改广告",
|
||||
visible: true,
|
||||
}
|
||||
const advertId = row.id || state.ids
|
||||
getAdvertDetail(advertId).then((response) => {
|
||||
state.formData = response.data
|
||||
})
|
||||
};
|
||||
const advertId = row.id || state.ids;
|
||||
getAdvertFormDetail(advertId).then((response) => {
|
||||
state.formData = response.data;
|
||||
});
|
||||
}
|
||||
|
||||
function submitForm() {
|
||||
const dataForm = unref(dataFormRef)
|
||||
dataForm.validate((valid: any) => {
|
||||
dataFormRef.value.validate((valid: any) => {
|
||||
if (valid) {
|
||||
const avertId = state.formData.id
|
||||
const avertId = state.formData.id;
|
||||
if (avertId) {
|
||||
updateAdvert(avertId, state.formData).then(response => {
|
||||
ElMessage.success('修改成功')
|
||||
state.dialog.visible = false
|
||||
handleQuery()
|
||||
})
|
||||
updateAdvert(avertId, state.formData).then((response) => {
|
||||
ElMessage.success("修改成功");
|
||||
cancel();
|
||||
handleQuery();
|
||||
});
|
||||
} else {
|
||||
addAdvert(state.formData).then(response => {
|
||||
ElMessage.success('新增成功')
|
||||
state.dialog.visible = false
|
||||
handleQuery()
|
||||
})
|
||||
addAdvert(state.formData).then((response) => {
|
||||
ElMessage.success("新增成功");
|
||||
cancel();
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置表单
|
||||
*/
|
||||
function resetForm() {
|
||||
state.formData = {
|
||||
id: undefined,
|
||||
title: '',
|
||||
picUrl: '',
|
||||
beginTime: undefined,
|
||||
endTime: undefined,
|
||||
status: 1,
|
||||
sort: 100,
|
||||
url: undefined,
|
||||
remark: undefined
|
||||
}
|
||||
state.formData.id = undefined;
|
||||
dataFormRef.value.resetFields();
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
resetForm()
|
||||
state.dialog.visible = false
|
||||
resetForm();
|
||||
state.dialog.visible = false;
|
||||
}
|
||||
|
||||
function handleDelete(row: any) {
|
||||
const ids = [row.id || state.ids].join(',')
|
||||
ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
deleteAdverts(ids).then(() => {
|
||||
ElMessage.success('删除成功')
|
||||
handleQuery()
|
||||
const ids = [row.id || state.ids].join(",");
|
||||
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
deleteAdverts(ids).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
handleQuery();
|
||||
});
|
||||
})
|
||||
}).catch(() =>
|
||||
ElMessage.info('已取消删除')
|
||||
)
|
||||
.catch(() => ElMessage.info("已取消删除"));
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery()
|
||||
})
|
||||
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -261,6 +261,7 @@ async function loadDeptOptions() {
|
||||
* 表单重置
|
||||
**/
|
||||
function resetForm() {
|
||||
state.formData.id = undefined;
|
||||
dataFormRef.value.resetFields();
|
||||
}
|
||||
|
||||
|
||||
@@ -238,6 +238,7 @@ function submitForm() {
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
state.formData.id = undefined;
|
||||
dataFormRef.value.resetFields();
|
||||
}
|
||||
|
||||
|
||||
@@ -277,6 +277,7 @@ function submitForm() {
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
state.formData.id = undefined;
|
||||
dataFormRef.value.resetFields();
|
||||
}
|
||||
|
||||
|
||||
@@ -403,6 +403,7 @@ function handleDelete(row: any) {
|
||||
* 重置表单
|
||||
*/
|
||||
function resetForm() {
|
||||
state.formData.id = undefined;
|
||||
dataFormRef.value.resetFields();
|
||||
}
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ import {
|
||||
UserFormData,
|
||||
Option,
|
||||
RoleItem,
|
||||
Dialog,
|
||||
Dialog
|
||||
} from "@/types";
|
||||
|
||||
// DOM元素的引用声明定义
|
||||
@@ -559,6 +559,7 @@ function submitForm() {
|
||||
* 重置表单
|
||||
*/
|
||||
function resetForm() {
|
||||
state.formData.id = undefined;
|
||||
dataFormRef.value.resetFields();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,85 +1,94 @@
|
||||
<template>
|
||||
<div class="component-container">
|
||||
<el-form
|
||||
ref="queryForm"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
>
|
||||
<div class="app-container">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-input
|
||||
v-model="queryParams.nickName"
|
||||
placeholder="会员昵称"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"/>
|
||||
v-model="queryParams.nickName"
|
||||
placeholder="会员昵称"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table v-loading="loading"
|
||||
:data="pageList"
|
||||
border
|
||||
@selection-change="handleSelectionChange"
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="memberList"
|
||||
border
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" align="center"/>
|
||||
<el-table-column type="expand" width="80" label="会员地址">
|
||||
<el-table-column type="selection" align="center" />
|
||||
<el-table-column type="expand" width="120" label="会员地址">
|
||||
<template #default="scope">
|
||||
<el-table
|
||||
:data="scope.row.addressList"
|
||||
size="small"
|
||||
border>
|
||||
<el-table-column type="index" label="序号" width="80" align="center"/>
|
||||
<el-table-column align="center" label="收货人" prop="name"/>
|
||||
<el-table-column align="center" label="联系方式" prop="mobile"/>
|
||||
<el-table :data="scope.row.addressList" size="small" border>
|
||||
<el-table-column
|
||||
type="index"
|
||||
label="序号"
|
||||
width="100"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column align="center" label="收货人" prop="name" />
|
||||
<el-table-column align="center" label="联系方式" prop="mobile" />
|
||||
<el-table-column align="center" label="收货地址">
|
||||
<template #default="scope">
|
||||
{{ scope.row.province + scope.row.city + scope.row.area + scope.row.address }}
|
||||
{{
|
||||
scope.row.province +
|
||||
scope.row.city +
|
||||
scope.row.area +
|
||||
scope.row.address
|
||||
}}
|
||||
</template>
|
||||
</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="是否默认">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.defaulted==1" type="success">是</el-tag>
|
||||
<el-tag v-if="scope.row.defaulted==0" type="info">否</el-tag>
|
||||
<el-tag v-if="scope.row.defaulted == 1" type="success"
|
||||
>是</el-tag
|
||||
>
|
||||
<el-tag v-if="scope.row.defaulted == 0" type="info">否</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column type="index" label="序号" width="50" align="center"/>
|
||||
<el-table-column prop="nickName" label="昵称"/>
|
||||
<el-table-column type="index" label="序号" width="100" align="center" />
|
||||
<el-table-column prop="nickName" label="昵称" />
|
||||
<el-table-column label="性别" width="80">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.gender===0">未知</span>
|
||||
<span v-if="scope.row.gender===1">男</span>
|
||||
<span v-if="scope.row.gender===2">女</span>
|
||||
<span v-if="scope.row.gender === 0">未知</span>
|
||||
<span v-if="scope.row.gender === 1">男</span>
|
||||
<span v-if="scope.row.gender === 2">女</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="头像" width="100">
|
||||
<template #default="scope">
|
||||
<el-popover
|
||||
placement="right"
|
||||
:width="400"
|
||||
trigger="hover">
|
||||
<img :src="scope.row.avatarUrl" width="400" height="400"/>
|
||||
<el-popover placement="right" :width="400" trigger="hover">
|
||||
<img :src="scope.row.avatarUrl" width="400" height="400" />
|
||||
<template #reference>
|
||||
<img :src="scope.row.avatarUrl" style="max-height: 60px;max-width: 60px"/>
|
||||
<img
|
||||
:src="scope.row.avatarUrl"
|
||||
style="max-height: 60px; max-width: 60px"
|
||||
/>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="mobile" label="手机号码"/>
|
||||
<el-table-column prop="birthday" label="出生日期"/>
|
||||
<el-table-column prop="mobile" label="手机号码" />
|
||||
<el-table-column prop="birthday" label="出生日期" />
|
||||
<el-table-column prop="status" width="80" label="状态">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status===1" type="success" >正常</el-tag>
|
||||
<el-tag v-else type="info" >禁用</el-tag>
|
||||
<el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
|
||||
<el-tag v-else type="info">禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="gmtCreate" label="注册时间"/>
|
||||
<el-table-column prop="gmtCreate" label="注册时间" />
|
||||
|
||||
<el-table-column label="账户余额">
|
||||
<template #default="scope">
|
||||
@@ -90,21 +99,22 @@
|
||||
|
||||
<!-- 分页工具条 -->
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {reactive, onMounted, toRefs} from 'vue'
|
||||
import {ElTable, ElMessage, ElMessageBox} from 'element-plus'
|
||||
import {Search, Plus, Edit, Refresh, Delete} from '@element-plus/icons-vue'
|
||||
import { reactive, onMounted, toRefs } from "vue";
|
||||
import { ElTable, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
|
||||
import {listMembersWithPage} from '@/api/ums/member'
|
||||
import { listMemeberPages } from "@/api/ums/member";
|
||||
import { MemberQueryParam,MemberItem } from "@/types";
|
||||
|
||||
const state = reactive({
|
||||
// 遮罩层
|
||||
@@ -119,21 +129,20 @@ const state = reactive({
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
nickName: undefined
|
||||
},
|
||||
pageList: []
|
||||
})
|
||||
} as MemberQueryParam,
|
||||
memberList: [] as MemberItem[]
|
||||
});
|
||||
|
||||
const { loading,ids,single, multiple, queryParams, pageList,total} = toRefs(state);
|
||||
const { loading, ids, single, multiple, queryParams, memberList, total } =
|
||||
toRefs(state);
|
||||
|
||||
function handleQuery() {
|
||||
state.loading = true
|
||||
listMembersWithPage(state.queryParams).then(response => {
|
||||
const {data, total} = response as any
|
||||
state.pageList = data
|
||||
state.total = total
|
||||
state.loading = false
|
||||
})
|
||||
state.loading = true;
|
||||
listMemeberPages(state.queryParams).then(({data}) => {
|
||||
state.memberList = data.list;
|
||||
state.total = data.total;
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
@@ -141,21 +150,19 @@ function resetQuery() {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
nickName: undefined,
|
||||
}
|
||||
handleQuery()
|
||||
};
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection: any) {
|
||||
state.ids = selection.map((item: { id: any }) => item.id)
|
||||
state.single = selection.length != 1
|
||||
state.multiple = !selection.length
|
||||
state.ids = selection.map((item: { id: any }) => item.id);
|
||||
state.single = selection.length != 1;
|
||||
state.multiple = !selection.length;
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery()
|
||||
})
|
||||
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user