416 lines
14 KiB
Vue
416 lines
14 KiB
Vue
<!-- 存酒记录 -->
|
||
<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> |