Files
cashier_desktop/src/views/store_wine/components/managePage.vue
2026-05-09 08:53:40 +08:00

416 lines
14 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="wrap">
<div class="top_wrap">
<el-form :model="queryForm" inline>
<el-form-item label="酒名">
<el-input v-model="queryForm.name" placeholder="请输入酒名"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" :loading="tableData.loading"
@click="storageGoodGetAjax">搜索</el-button>
<el-button icon="Refresh" :loading="tableData.loading" @click="reset">重置</el-button>
</el-form-item>
</el-form>
<el-button type="primary" @click="addFormDialogShow = true">新增酒品</el-button>
</div>
<div class="tab">
<div class="tab_wrap">
<el-table :data="tableData.list" v-loading="tableData.loading" border stripe height="100%">
<el-table-column label="酒品名">
<template v-slot="scope">
<div class="center">
<el-avatar :size="40" shape="square" :src="scope.row.imgUrl" style="flex-shrink: 0;">
{{ scope.row.name.charAt(0) }}
</el-avatar>
<el-text>{{ scope.row.name }}</el-text>
</div>
</template>
</el-table-column>
<el-table-column label="单位" prop="unit"></el-table-column>
<el-table-column label="有效期(天)" prop="period"></el-table-column>
<el-table-column label="来源" prop="source" width="100">
<template v-slot="scope">
<el-text v-if="scope.row.source === 1">商品</el-text>
<el-text v-if="scope.row.source === 0">手动</el-text>
</template>
</el-table-column>
<el-table-column label="操作" width="300">
<template #default="{ row }">
<el-button type="primary" @click="storeHandle(row)">存酒</el-button>
<el-button @click="editorHandle(row)">编辑</el-button>
<el-button type="danger" @click="deleteHandle(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="pagination">
<el-pagination background v-model:current-page="tableData.page" v-model:page-size="tableData.size"
:page-sizes="[10, 30, 50, 100]" layout="sizes, pager, jumper, total" :total="tableData.total"
@size-change="storageGoodGetAjax" @current-change="storageGoodGetAjax"></el-pagination>
</div>
<!-- 添加/编辑存酒 -->
<el-dialog :title="addForm.id ? '编辑酒品' : '添加酒品'" width="600px" v-model="addFormDialogShow"
@close="addFormDialogClsoe">
<el-form ref="addFormRef" :model="addForm" :rules="addFormRules" label-width="120" label-position="right">
<el-form-item label="类型">
<el-radio-group v-model="addForm.source">
<el-radio-button label="手动添加" :value="0"></el-radio-button>
<el-radio-button label="从商品添加" :value="1"></el-radio-button>
</el-radio-group>
</el-form-item>
<div v-if="addForm.source === 0">
<el-form-item label="酒品名" prop="name">
<el-input placeholder="请输入酒品名称" v-model="addForm.name" style="width: 80%;"></el-input>
</el-form-item>
<el-form-item label="酒品图片">
<UploadImg ref="UploadImgRef" @success="e => addForm.imgUrl = e" />
</el-form-item>
<el-form-item label="单位">
<el-input placeholder="请输入单位" v-model="addForm.unit" style="width: 50%;"></el-input>
</el-form-item>
</div>
<div v-else>
<el-form-item label="选择商品">
<el-select v-model="addForm.prodId" style="width: 80%;">
<el-option v-for="item in goodsStore.originGoodsList" :label="item.name" :value="item.id"
:key="item.id" @click="selectGoods(item)"></el-option>
</el-select>
</el-form-item>
<el-form-item label="商品名称">
<el-text v-if="addForm.name">{{ addForm.name }}</el-text>
<el-text type="info" v-else>请选择商品</el-text>
</el-form-item>
<el-form-item label="商品图片">
<el-image :src="addForm.imgUrl" style="width: 140px;height: 140px;"></el-image>
</el-form-item>
</div>
<el-form-item label="有效期">
<el-input-number v-model="addForm.period" :min="1" :step="1" step-strictly></el-input-number>
</el-form-item>
</el-form>
<div class="dialog-footer">
<div class="btn">
<el-button style="width: 100%;" @click="addFormDialogShow = false">
取消
</el-button>
</div>
<div class="btn">
<el-button style="width: 100%;" type="primary" :loading="addFormConfirmLoading"
@click="addFormConfirm">
确定
</el-button>
</div>
</div>
</el-dialog>
<!-- 存酒 -->
<el-dialog v-model="dialogVisible" :title="`${form.name} - 新增存酒`" width="400px" :close-on-click-modal="false"
destroy-on-close @close="storeInClose">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" label-position="left">
<el-form-item label="选择用户" prop="userId">
<el-select v-model="form.userId" placeholder="请选择用户(可搜索)" clearable filterable remote
remote-show-suffix :remote-method="remoteMethod" :loading="userListLoading"
@clear="getUserList">
<el-option :label="`${item.nickName}/${item.phone}`" :value="item.userId"
v-for="item in userList" :key="item.id"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="选择酒品">
<el-select v-model="form.shopStorageGoodId" placeholder="请选择存酒商品">
<el-option v-for="item in storageGoodList" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item> -->
<el-form-item label="存酒数量">
<el-input-number v-model="form.num" :min="1" :step="1" step-strictly></el-input-number>
</el-form-item>
<el-form-item label="存酒有效期">
<el-input-number v-model="form.expDay" :min="1" :step="1" step-strictly></el-input-number>
<span style="margin-left: 8px;"></span>
</el-form-item>
</el-form>
<div class="dialog-footer">
<div class="btn">
<el-button style="width: 100%;" @click="dialogVisible = false"> </el-button>
</div>
<div class="btn">
<el-button style="width: 100%;" type="primary" :loading="confirmLoading" @click="confirmHandle">
</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import _ from 'lodash'
import { ref, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { shopStoragePost, storageGoodGet, storageGoodPost, storageGoodPut, storageGoodDelete } from '@/api/product_new'
import { shopUserList } from '@/api/account.js'
import UploadImg from '@/components/uploadImg.vue'
import { useGoods } from '@/store/goods.js'
const goodsStore = useGoods()
const UploadImgRef = ref(null)
const queryForm = ref({
name: ''
})
const tableData = ref({
loading: false,
page: 1,
size: 10,
total: 0,
list: []
});
function isExpired(expTime) {
if (!expTime) return false;
const now = new Date();
const expDate = new Date(expTime);
return expDate < now;
}
function reset() {
queryForm.value.name = ''
tableData.page = 1
storageGoodGetAjax()
}
const userList = ref([])
// 获取用户列表
const userListLoading = ref(false)
function remoteMethod(query) {
if (query) {
getUserList(query)
}
}
// 获取用户列表
async function getUserList(name = '') {
try {
userListLoading.value = true
const res = await shopUserList({ page: 1, key: name, size: 20 })
userList.value = res.records
} catch (error) {
console.log(error);
} finally {
setTimeout(() => {
userListLoading.value = false
}, 100);
}
}
// 获取存酒商品列表
const storageGoodList = ref([]);
async function storageGoodGetAjax() {
try {
tableData.value.loading = true
const res = await storageGoodGet({
name: queryForm.value.name,
page: tableData.value.page,
size: tableData.value.size,
});
tableData.value.list = res.records || [];
tableData.value.total = +res.totalRow || 0
} catch (error) {
console.error('获取存酒商品列表失败:', error);
} finally {
setTimeout(() => {
tableData.value.loading = false
}, 300);
}
}
const dialogVisible = ref(false);
const formObj = {
name: '',
userId: '',
shopStorageGoodId: '', // 存酒商品ID
num: 1, // 存酒数量
expDay: 1, // 存酒有效期单位天默认1天
}
const formRef = ref(null)
const form = ref(formObj)
const rules = {
userId: [{ required: true, message: '请选择用户', trigger: 'change' }],
shopStorageGoodId: [{ required: true, message: '请选择存酒商品', trigger: 'change' }],
num: [{ required: true, message: '请输入存酒数量', trigger: 'change' }],
expDay: [{ required: true, message: '请输入存酒有效期', trigger: 'change' }],
}
function storeInClose() {
formRef.value.resetFields()
form.value = _.cloneDeep(formObj)
}
// 确认存酒
const confirmLoading = ref(false);
function confirmHandle() {
formRef.value.validate(async vaild => {
try {
if (vaild) {
confirmLoading.value = true;
await shopStoragePost(form.value);
ElMessage.success('存酒成功');
dialogVisible.value = false;
}
} catch (error) {
console.error('存酒失败:', error);
} finally {
confirmLoading.value = false;
}
})
}
// 添加酒品
const addFormDialogShow = ref(false)
const addFormRef = ref(null)
const addFormObj = {
id: '',
name: '', // 酒品名称
imgUrl: '', // 商品图片
unit: '瓶', // 单位
period: 365, // 过期时间
prodId: '', // 商品id
source: 0, // 0手动 1商品
}
const addForm = ref(_.cloneDeep(addFormObj))
const addFormRules = ref({
name: [
{
required: true,
message: '请输入酒品名称',
trigger: 'blur'
}
]
})
// 显示存酒
async function storeHandle(row) {
form.value.name = row.name
form.value.shopStorageGoodId = row.id
await nextTick()
dialogVisible.value = true
}
// 编辑
async function editorHandle(row) {
addForm.value = _.cloneDeep(row)
addFormDialogShow.value = true
if (row.source == 0) {
await nextTick()
UploadImgRef.value.init([{ url: row.imgUrl }])
}
}
// 删除
function deleteHandle(row) {
ElMessageBox.confirm(`确认要删除酒品「${row.name}」吗?`).then(async () => {
try {
tableData.value.loading = true
await storageGoodDelete(row.id)
reset()
} catch (error) {
tableData.value.loading = false
}
}).catch(() => { })
}
// 选择商品
function selectGoods(item) {
addForm.value.name = item.name
addForm.value.imgUrl = item.coverImg
}
function addFormDialogClsoe() {
addFormRef.value.resetFields()
addForm.value = _.cloneDeep(addFormObj)
if (form.value.source == 0) {
UploadImgRef.value.init([])
}
}
const addFormConfirmLoading = ref(false)
function addFormConfirm() {
addFormRef.value.validate(async vaild => {
try {
if (vaild) {
addFormConfirmLoading.value = true
if (addForm.value.id) {
await storageGoodPut(addForm.value)
} else {
await storageGoodPost(addForm.value)
}
ElMessage.success(addForm.value.id ? '编辑成功' : '添加成功')
addFormDialogShow.value = false
reset()
}
} catch (error) {
console.log(error);
} finally {
setTimeout(() => {
addFormConfirmLoading.value = false
}, 300);
}
})
}
onMounted(() => {
storageGoodGetAjax()
getUserList()
})
</script>
<style scoped lang="scss">
.wrap {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.tab {
flex: 1;
position: relative;
.tab_wrap {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
.center {
display: flex;
align-items: center;
gap: 10px;
}
.top_wrap {
display: flex;
justify-content: space-between;
}
.pagination {
padding-top: var(--el-font-size-base);
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: var(--el-font-size-base);
.btn {
flex: 1;
}
}
</style>