2025-08-14 11:17:19 +08:00

443 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="p-2">
<div v-show="show">
<el-card shadow="hover" class="mb-[10px]">
<el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="default" class="ry_form">
<el-form-item label="上架状态" prop="publishStatus">
<DictRadio v-model="queryParams.publishStatus" @change="handleQuery" radioData="pms_publish_status" :showAll="'all'" />
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="queryParams.nameLike" placeholder="请输入商品名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="品牌" prop="brandId">
<el-select v-model="queryParams.brandId" placeholder="请选择品牌" clearable @change="handleQuery">
<el-option v-for="item in getbrandList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="分类" prop="categoryId">
<el-select v-model="queryParams.categoryId" placeholder="请选择分类" clearable @change="handleQuery">
<el-option v-for="item in getCategoryNameLike" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="编码" prop="outProductId">
<el-input v-model="queryParams.outProductId" placeholder="请输入商品编码" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item class="flex_one tr">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card shadow="hover">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
</el-col>
</el-row>
</template>
<el-table v-loading="loading" :data="pmsProductList" border>
<el-table-column label="店铺名称" min-width="120" prop="contactUserName" align="center"> </el-table-column>
<el-table-column label="店铺手机号" prop="contactPhone" min-width="115" align="center"> </el-table-column>
<el-table-column label="配送方式" prop="distribution" align="center">
<template v-slot="scope">{{ scope.row.distribution == 1 ? '到店核销' : scope.row.distribution == 2 ? '自提' : '配送' }} </template>
</el-table-column>
<el-table-column label="商品名称" prop="name" align="center"> </el-table-column>
<el-table-column label="商品类型" prop="type" align="center">
<template v-slot="scope">{{ scope.row.type == 1 ? '团购' : scope.row.type == 2 ? '拼团' : '秒杀' }} </template>
</el-table-column>
<el-table-column label="商品分类" prop="productCategoryName" align="center"> </el-table-column>
<el-table-column label="商品封面图" prop="pic" width="100" align="center">
<template v-slot="scope">
<el-image v-if="scope.row.pic" :src="scope.row.pic" class="small-img" />
</template>
</el-table-column>
<el-table-column label="商品轮播图" prop="albumPics" width="100" align="center">
<template v-slot="scope">
<el-image
v-if="scope.row.albumPics"
:src="scope.row.pic"
:preview-teleported="true"
class="small-img"
:preview-src-list="isimgfun(scope.row.albumPics)"
/>
</template>
</el-table-column>
<el-table-column label="商品详情" prop="detailHtml" align="center"> </el-table-column>
<el-table-column label="原价" prop="price" align="center"> </el-table-column>
<el-table-column label="优惠金额" prop="discountPrice" align="center"> </el-table-column>
<el-table-column label="销量" prop="sales" align="center"> </el-table-column>
<el-table-column label="商品状态" prop="publishStatus" fixed="right" align="center">
<template v-slot="scope">
<el-switch
:model-value="scope.row.publishStatus"
:active-value="1"
:inactive-value="0"
active-text="上架"
inactive-text="下架"
inline-prompt
:before-change="
() => {
return handleChangeUserStatus(scope.row);
}
"
>
</el-switch> </template
></el-table-column>
<el-table-column label="审核状态" prop="authFlag" fixed="right" min-width="110" align="center">
<template v-slot="scope">
{{ scope.row.authFlag == 1 ? '待审核' : scope.row.authFlag == 2 ? '审核通过' : '审核驳回' }}
</template></el-table-column
>
<el-table-column label="操作" class-name="small-padding fixed-width" width="150" align="center" fixed="right">
<template v-slot="scope">
<el-button text type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改 </el-button>
<br />
<el-button text type="primary" icon="Edit" @click="handleAuth(scope.row)">审核</el-button>
<br />
<el-button text type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<el-dialog title="商品审核" v-model="isAuthModalOpen" width="600px">
<el-form label-width="auto" ref="authForm" size="default">
<el-form-item label="审核状态" prop="authFlag">
<el-radio-group v-model="authInfo.authFlag">
<el-radio label="2">通过</el-radio>
<el-radio label="3">驳回</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="反驳理由" prop="authRemark" v-if="authInfo.authFlag === '3'">
<el-input v-model.trim="authInfo.reasons" placeholder="请输入反驳理由" />
</el-form-item>
<el-form-item prop="authRemark">
<el-button type="primary" @click="authInfoProduct">确认</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!--编辑会员基础信息-->
<el-dialog title="编辑商品详情" v-model="productModalInfo.open" width="600px" append-to-body>
<el-form label-width="auto" :rules="productEditRules" :model="productModalInfo.data" ref="editForm" size="default">
<el-form-item label="昵称" prop="nickname">
<el-input v-model.trim="productModalInfo.data.nickname" placeholder="请输入会员昵称" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model.trim="productModalInfo.data.password" placeholder="请输入会员密码" />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model.trim="productModalInfo.data.phone" placeholder="请输入会员手机号" />
</el-form-item>
<el-form-item label="备注" prop="mark">
<el-input v-model.trim="productModalInfo.data.mark" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-switch
:active-value="1"
:inactive-value="0"
active-text="启用"
inactive-text="禁用"
inline-prompt
v-model="productModalInfo.data.status"
/>
</el-form-item>
<el-form-item label="头像" prop="avatar">
<!-- 暂时先用输入框组件后续OSS上传功能好了迁移到上传upload组件-->
<el-input v-model.trim="productModalInfo.data.avatar" placeholder="请输入头像" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<DictRadio v-model="productModalInfo.data.gender" radioData="sys_user_sex" :show-all="'all'" />
</el-form-item>
<el-form-item label="地址" prop="address">
<AddressSelector v-model="productModalInfo.data.fullArea" style="width: 100%" />
</el-form-item>
<el-form-item label="生日" prop="birthday">
<el-input v-model.trim="productModalInfo.data.birthday" placeholder="请选择生日" />
</el-form-item>
<el-form-item label="用户等级" prop="level">
<el-input v-model.trim="productModalInfo.data.level" placeholder="请输入用户等级" />
</el-form-item>
<el-form-item label="剩余积分" prop="integral">
<el-input v-model.trim="productModalInfo.data.integral" placeholder="请输入剩余积分" />
</el-form-item>
<el-row>
<el-col :span="12"> </el-col>
<el-col :span="12">
<el-button type="danger" @click="closeEditProduct">关闭</el-button>
<el-button type="primary" @click="submitEditProduct">保存</el-button>
</el-col>
</el-row>
</el-form>
</el-dialog>
</div>
<!-- <SeeAdsComponent ref="seeAdsComponentRef" v-if="!show" @confirmOk="confirmOk"/>-->
</div>
</template>
<script>
import { delPmsProduct, listPmsProduct, productpublish, productaudit, getproductCategoryNameLike, getbrand } from '@/api/pms/product';
import { isStarRepo } from '@/utils/is-star-plugin';
import { useUserStore } from '@/store/modules/user';
import AddressSelector from '@/views/components/AddressSelector/index.vue';
import { editUserData } from '@/api/ums/member.js';
export default {
name: 'PmsProduct',
components: { AddressSelector },
dicts: ['pms_publish_status'],
data() {
return {
authInfo: {
id: '',
authFlag: 1,
reasons: ''
},
//审核弹出
isAuthModalOpen: false,
show: true,
// 遮罩层
loading: true,
// 导出遮罩层
exportLoading: false,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 商品信息表格数据
pmsProductList: [],
productModalInfo: {
open: false,
data: {}
},
productEditRules: {
nickname: [{ required: true, message: '昵称不能为空', trigger: 'blur' }],
/*password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],*/
/* address: [{ required: true, message: '地址不能为空', trigger: 'change' }],*/
/* avatar: [{ required: true, message: '头像不能为空', trigger: 'change' }],*/
/* gendor: [{ required: true, message: '性别不能为空', trigger: 'change' }],*/
birthday: [{ required: true, message: '生日不能为空', trigger: 'change' }],
level: [{ required: true, message: '用户等级不能为空', trigger: 'blur' }],
integral: [{ required: true, message: '积分不能为空', trigger: 'blur' }],
/* email: [{ type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] }],*/
phone: [{ required: true, pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }]
},
getCategoryNameLike: [],
getbrandList: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
brandId: null,
categoryId: null,
outProductId: null,
name: null,
pic: null,
albumPics: null,
publishStatus: null,
sort: null,
price: null,
unit: null,
weight: null,
detailHtml: null,
detailMobileHtml: null,
brandName: null,
productCategoryName: null,
brandId: null
}
};
},
created() {
this.getList();
this.getgetproductCategoryNameLike();
this.getbrand();
},
computed: {
userId: {
get() {
return useUserStore().userId;
}
}
},
methods: {
// 查询商品分类列表
async getgetproductCategoryNameLike() {
const res = await getproductCategoryNameLike();
this.getCategoryNameLike = res.data;
},
// 查询商品分类列表
async getbrand() {
const res = await getbrand();
this.getbrandList = res.data;
},
//审核
async authInfoProduct() {
const res = await productaudit(this.authInfo, this.authInfo);
if (res.code == 200) {
this.getList();
this.$modal.msgSuccess('审核成功');
this.isAuthModalOpen = false;
this.authInfo = {
id: '',
authFlag: 1,
reasons: ''
};
}
},
handleAuth(row) {
this.authInfo.id = row.id;
this.isAuthModalOpen = true;
},
//上下架
async handleChangeUserStatus(row) {
await ElMessageBox.confirm(row.publishStatus == 0 ? '确定要上架该商品吗?' : '确定要下架该商品吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
if (row.publishStatus == 0) {
const res = await productpublish({ id: row.id, publishStatus: 1 }, { id: row.id, publishStatus: 1 });
console.log(res.code);
if (res.code == 200) {
this.getList();
this.$modal.msgSuccess('上架成功');
}
} else {
const res = await productpublish({ id: row.id, publishStatus: 0 }, { id: row.id, publishStatus: 0 });
if (res.code == 200) {
this.getList();
this.$modal.msgSuccess('下架成功');
}
}
});
},
isimgfun(url) {
if (!url || typeof url !== 'string') {
console.log('无效的 URL 输入');
return [];
}
const urls = url.split(',');
// 过滤掉空的 URL
const validUrls = urls.filter((item) => item.trim() !== '');
return validUrls;
},
submitEditProduct() {
this.$refs['editForm'].validate((valid) => {
if (valid) {
const { fullArea } = this.userAccountEditModal.data || {};
const params = {
...this.userAccountEditModal.data
};
if (fullArea && fullArea.length) {
const [province = '', city = '', district = ''] = fullArea;
params.province = province;
params.city = city;
params.district = district;
}
editUserData(params).then((response) => {
this.$modal.msgSuccess('修改成功');
this.closeEditUser();
this.getList();
});
}
});
},
closeEditProduct() {
this.productModalInfo = {
open: false,
data: {}
};
},
// 编辑商品详情弹框
showProductEditModal(record) {
this.productModalInfo = {
data: { ...record, gender: String(record.gender) } || {},
open: true
};
},
async confirmOk(success) {
if (success) {
const res = await isStarRepo(
'zccbbg',
'RuoYi-Mall',
this.userId,
'https://mall.ichengle.top/pms/product',
'ruoyi-mall-商城',
'https://gitee.com/zccbbg/RuoYi-Mall'
);
this.show = res;
if (res) {
this.getList();
}
}
},
/** 查询商品信息列表 */
getList() {
this.loading = true;
const { pageNum, pageSize } = this.queryParams;
const query = { ...this.queryParams, pageNum: undefined, pageSize: undefined };
const pageReq = { current: pageNum - 1, size: pageSize };
listPmsProduct(query, pageReq).then((response) => {
const { records, total } = response.data || {};
this.pmsProductList = records;
this.total = total;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm');
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map((item) => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push({ path: '/product/edit' });
},
/** 修改按钮操作 */
handleUpdate(row) {
this.$router.push({ path: '/product/edit', query: { id: row.id } });
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal
.confirm('是否确认删除商品信息编号为"' + ids + '"的数据项?')
.then(function () {
return delPmsProduct(ids);
})
.then(() => {
this.$modal.msgSuccess('删除成功');
this.getList();
})
.catch(() => {});
}
}
};
</script>
<style scoped lang="scss">
::v-deep {
.el-image-viewer__canvas {
z-index: 9999;
}
}
</style>