Files
cmgd-mini-app/pages/control/goods/index.vue-
2026-01-05 12:47:14 +08:00

429 lines
11 KiB
Plaintext

<template>
<view class="page-content">
<nut-searchbar shape="square" placeholder="请输入商品串号" clearable v-model="search_val" input-background="#eee" @search="onSearch"
@clear="onClear">
<template #rightout>
<nut-icon @click="onScan" name="scan2" size="30" custom-color="#000000" />
</template>
</nut-searchbar>
<view v-if="goods_ids_with_goods_no_list.length > 0" class="list">
<view @click="getGoodsDetail(item.goods_id)" class="list-item" :key="idx"
v-for="(item,idx) in goods_ids_with_goods_no_list">
{{ item.goods_no }}
</view>
</view>
<view v-if="is_show_detail" style=" padding: 20rpx;">
<nut-form>
<nut-form-item label="名称">
<nut-input v-model="form.goods_name" class="nut-input-text" placeholder="请输入名称" type="text" />
</nut-form-item>
<nut-form-item label="价格">
<nut-input v-model="form.goods_price" class="nut-input-text" placeholder="请输入价格" type="nubmer" />
</nut-form-item>
<nut-form-item label="串号">
<nut-input v-model="form.goods_no" class="nut-input-text" placeholder="请输入串号" type="text" readonly disabled/>
</nut-form-item>
<nut-form-item label="介绍">
<nut-textarea v-model="form.content" autosize placeholder="请输入介绍" type="text" />
</nut-form-item>
<!-- <nut-form-item label="上架人">
<nut-input v-model="form.add_person" class="nut-input-text" placeholder="请输入上架人" type="text" />
</nut-form-item> -->
<!-- <nut-form-item label="排序">
<nut-input v-model="form.goods_sort" class="nut-input-text" placeholder="请输入排序" type="number" />
</nut-form-item> -->
<!-- <nut-form-item label="状态">
<nut-radio-group direction="horizontal" v-model="form.goods_status">
<nut-radio label="10">上架</nut-radio>
<nut-radio label="20">下架</nut-radio>
</nut-radio-group>
</nut-form-item> -->
<nut-form-item>
<template v-slot:label>成色</template>
<template v-slot:default>
<view style="color: black;" @click="show_degree_popup = true">
<text>{{form.degree_name}}</text>
</view>
</template>
</nut-form-item>
<nut-form-item>
<template v-slot:label>机型</template>
<template v-slot:default>
<view style="color: black;" @click="show_product_cascader = true">
<text>{{form.type_name}},{{form.brand_name}},{{form.product_name}}</text>
</view>
</template>
</nut-form-item>
<nut-form-item>
<template v-slot:label>商品图片</template>
<template v-slot:default>
<shmily-drag-image v-model="form.images" :number=9 :add-image="addGoodsImg"
keyName="file_path"></shmily-drag-image></template>
</nut-form-item>
<nut-form-item>
<template v-slot:label>验机报告</template>
<template v-slot:default>
<view @click="show_report_tags_popup = true">
<text>点击勾选</text>
</view>
</template>
</nut-form-item>
<view style="align-items: center;text-align: center; padding: 20rpx 0rpx;">
<nut-button type="primary" @click="onSubmit">
保存修改
</nut-button>
</view>
</nut-form>
</view>
<nut-popup :custom-style="{ height: '50%' }" v-model:visible="show_report_tags_popup" position="bottom"
safe-area-inset-bottom>
<view style="margin-left: 200rpx; margin-top: 30rpx;">
<!-- <DaTree ref="DaTreeRef" :data="report_tags" childrenField="value_list" labelField="name" valueField="id"
defaultExpandAll showCheckbox @change="handleTreeChange">
</DaTree> -->
<DaTree ref="DaTreeRef" :data="report_tags" childrenField="value_list" labelField="name" valueField="id"
:defaultExpandedKeys="defaultExpandKeys" showCheckbox @change="handleTreeChange">
</DaTree>
</view>
</nut-popup>
<nut-popup v-model:visible="show_degree_popup" position="bottom" safe-area-inset-bottom>
<nut-picker v-model="popup_degree_val" :columns="filter_params.degree_list"
:field-names="{text:'degree_name',value:'degree_id'}" title="选择成色" @confirm="onConfirmDegree"
@cancel="show_degree_popup = false">
</nut-picker>
</nut-popup>
<nut-cascader title="机型选择" v-model:visible="show_product_cascader" v-model="cascader_product_val"
@change="onProductChange" @pathChange="onProcutPathChange" text-key="label" value-key="value"
:title-ellipsis="false" children-key="children" :options="filter_params.drop_down_options"></nut-cascader>
</view>
</template>
<script setup>
import {
onMounted,
reactive,
ref,
toValue
} from 'vue';
import {
fetchGoodsDetail,
fetchGoodsList,
fetchFilterParmas,
fetchGoodsReportTags,
} from '../../../api/goods';
import {
getUploadImageUrl
} from '../../../api/request';
import {
DaTree
} from '@/components/da-tree/index.vue'
import {
fetchControlEditGoods,
fetchControlGoodsDetail,
fetchGoodsListByGoodsNo,
} from '../../../api/control';
import {
clearReactiveData
} from '../../../utils/helper';
// 是否显示结果页
const is_show_detail = ref(false);
// 搜索内容
const search_val = ref('')
// 商品详情
const detail = reactive({})
const filter_params = reactive({})
const report_tags = reactive([])
const all_report_tag_ids = ref([])
// 默认展开
const defaultExpandKeys = ref([0])
// 显示机型选择
const show_product_cascader = ref(false)
// 显示成色
const show_degree_popup = ref(false)
// 显示验机报告
const show_report_tags_popup = ref(false)
const popup_degree_val = ref([])
const cascader_product_val = ref([])
const DaTreeRef = ref()
// 搜索串号列表
const goods_ids_with_goods_no_list = ref([])
// 搜索
const onSearch = () => {
goods_ids_with_goods_no_list.value = [];
is_show_detail.value = false;
fetchGoodsListByGoodsNo(search_val.value).then(res => {
goods_ids_with_goods_no_list.value = res || []
})
}
// 清空搜索内容
const onClear = () => {
search_val.value = ''
is_show_detail.value = false;
goods_ids_with_goods_no_list.value = []
}
const form = reactive({
goods_name: '',
goods_id: 0,
content: '',
goods_price: '',
goods_no: '',
images: [],
// add_person: '',
// goods_status: '10',
// goods_sort: 0,
degree_id: 0,
degree_name: '未选择',
type_id: 0,
type_name: '未选择',
brand_id: 0,
brand_name: '未选择',
product_id: 0,
product_name: '未选择',
report_tag_ids: []
})
// 获取商品详情
const getGoodsDetail = (id) => {
fetchControlGoodsDetail(id).then(res => {
// 显示商品详情
is_show_detail.value = true;
Object.assign(detail, res)
goods_ids_with_goods_no_list.value = []
form.goods_name = res.goods_name
form.goods_id = res.goods_id
form.content = res.content
form.goods_price = res.goods_price
form.goods_no = res.goods_no
// form.add_person = res.add_person
// form.goods_status = res.goods_status.value.toString()
// form.goods_sort = res.goods_sort
form.degree_id = res.degree?.degree_id ?? 0
form.degree_name = res.degree?.degree_name ?? '未选择'
form.type_id = res.type?.type_id ?? 0
form.type_name = res.type?.name ?? '未选择'
form.brand_id = res.brand?.brand_id ?? 0
form.brand_name = res.brand?.name ?? '未选择'
form.product_id = res.product?.product_id ?? 0
form.product_name = res.product?.name ?? '未选择'
form.images = []
DaTreeRef.value?.setCheckedKeys(all_report_tag_ids.value, false)
let tag_ids = (res.report_tag_ids?.split(',') || []).map(Number)
form.report_tag_ids = tag_ids
DaTreeRef.value?.setCheckedKeys(tag_ids, true)
popup_degree_val.value = [res.degree?.degree_id ?? 0]
cascader_product_val.value = [res.type?.type_id ?? 0, res.brand?.brand_id ?? 0, res.product?.product_id??0]
res.image?.forEach(item => {
form.images.push({
id: item.image_id,
file_path: item.file_path,
})
})
})
}
const onProductChange = (...args) => {
// console.log(0,...args)
// console.log(cascader_product_val)
}
const handleTreeChange = (allSelectedKeys, currentItem) => {
form.report_tag_ids = allSelectedKeys
// console.log('handleTreeChange ==>', allSelectedKeys, currentItem)
}
const onSubmit = () => {
fetchControlEditGoods(form).then(res => {
uni.showToast({
icon: 'none',
title: '成功'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/control/goods/index',
success: res => {},
fail: () => {},
complete: () => {}
});
}, 500)
})
}
const onProcutPathChange = (args) => {
console.log(args);
form.type_id = 0
form.type_name = ''
form.brand_id = 0
form.brand_name = ''
form.product_id = 0
form.product_name = ''
if (args.length >= 1 && args[0] !== null) {
form.type_id = args[0].value
form.type_name = args[0].text
}
if (args.length >= 2 && args[1] !== null) {
form.brand_id = args[1].value
form.brand_name = args[1].text
}
if (args.length >= 3 && args[2] !== null) {
form.product_id = args[2].value
form.product_name = args[2].text
}
}
const onConfirmDegree = () => {
form.degree_id = popup_degree_val.value[0]
filter_params.degree_list.forEach(item => {
if (item.degree_id === form.degree_id) {
form.degree_name = item.degree_name
}
})
show_degree_popup.value = false
}
// 扫码
const onScan = () => {
uni.scanCode({
onlyFromCamera: true,
success: (res) => {
form.goods_no = res.result
search_val.value = res.result
fetchGoodsListByGoodsNo(res.result).then(res => {
if (res.length >= 1) {
getGoodsDetail(res[0]?.goods_id)
}
})
},
fail: () => {
uni.showToast({
icon: 'none',
title: '扫码失败'
})
}
})
}
onMounted(() => {
fetchFilterParmas(1).then(res => {
Object.assign(filter_params, res)
filter_params.degree_list.unshift({
degree_id: 0,
degree_name: '未选择'
})
console.log(filter_params)
})
fetchGoodsReportTags().then(res => {
Object.assign(report_tags, res)
console.log('report_tags',report_tags);
all_report_tag_ids.value = []
report_tags.forEach((report_tag, i) => {
all_report_tag_ids.value.push(report_tag.id)
console.log(report_tag.value_list)
report_tag.value_list.forEach((val, ii) => {
all_report_tag_ids.value.push(val.id)
val.value_list.forEach((vv, iii) => {
all_report_tag_ids.value.push(vv.id)
})
})
})
console.log(all_report_tag_ids)
})
})
// 上传商品图片
const addGoodsImg = () => {
uni.chooseImage({
count: 9 - (detail.image?.length || 0),
sourceType: ['album', 'camera'],
success: res => {
res.tempFiles.forEach(file => {
uni.uploadFile({
url: getUploadImageUrl(),
filePath: file.path,
name: 'iFile',
formData: {
group_id: 1,
},
success: (res) => {
let data = JSON.parse(res.data).data
form.images.push({
id: parseInt(data.file_id),
file_path: data.file_path,
})
}
})
})
}
})
}
</script>
<style lang="scss" scoped>
.page-content {
min-height: 100vh;
background-color: #f2f3f5;
}
.list {
display: flex;
justify-content: center;
flex-direction: column;
background: #ffffff;
align-items: center;
max-height: 300rpx;
overflow-y: scroll;
padding: 10px;
.list-item {
border-bottom: 1px solid #eee;
padding: 20rpx 10rpx;
}
}
</style>