货无忧安装平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

685 lines
17 KiB

<template>
<BasicContainer ref='basicContainer' :option="option">
<template #head>
<view class="server_container">
<view class="info_item_container ">
<view class="row flex-c-sb pb20" @click="handleShowChooseTypeOfMerchandise">
<text class="title pl20">商品类型</text>
<text class="info pr20">{{details.form.Merchandise||'请选择'}}</text>
</view>
<view class="row flex-c-sb pt20 pb20" @click="handleShowChooseTypeOfGoodsCategory">
<text class="title pl20">商品类目</text>
<text class="info pr20">{{details.form.GoodsCategory||'请选择'}}</text>
</view>
<view class="row flex-c-sb">
<text class="title pl20 mr20">单位</text>
<view class="input flex1">
<MyInput :border="false" :rules="{required: true, trigger: 'input', message: '请输入单位'}"
v-model="details.form.unit" clearable placeholder="请输入" />
</view>
</view>
<view class="row flex-c-sb">
<text class="title pl20">产品名称</text>
<view class="input flex1">
<MyInput v-model="details.form.product_name" clearable placeholder="请输入" />
</view>
</view>
<view class="row flex-c-sb">
<text class="title pl20">数量</text>
<view class="input flex1">
<MyInput v-model="details.form.number" type="number" :min="0"
@input="(e) => hadnleInputByNumber(e, 'number', 0)" placeholder="请输入" />
</view>
</view>
<view class="row flex-c-sb">
<text class="title pl20">单价</text>
<view class="input flex1">
<MyInput v-model="details.form.price" @input="(e) => hadnleInputByNumber(e, 'price', 2)"
type="number" :min="0" placeholder="请输入" />
</view>
</view>
<view class="row flex-c-sb pd20">
<text class="title">总价</text>
<text class="info">{{handleComputedMoney}}</text>
</view>
<view class="row pt20 pb20">
<view class="title pl20">
特殊要求
</view>
<view class="mt10 pl20">
<u-textarea v-model="details.form.remark"></u-textarea>
</view>
</view>
<view class="row border-none pt20">
<view class="title pl20">
图片
</view>
<!-- 图片列表 -->
<view class="mt10 imgList flex">
<!-- 单个图片 -->
<block v-for="(item, index) in details.imgList" :key="item">
<view class="image_conatiner mr20">
<image :src="item.url" mode=""></image>
<!-- 删除 -->
<view class="removeIcon" @click="()=> handleRmove(index)">
<u-icon name="close-circle-fill" color="#666" size="50"></u-icon>
</view>
</view>
</block>
<!-- 添加图片 -->
<view class="image_conatiner addImg flex-c-c" @click="handleUploadFile">
<u-icon name="photo-fill" color="#999" size="100"></u-icon>
</view>
</view>
</view>
</view>
<!-- 站位容器 -->
<!-- 提交按钮 -->
<view class="submitButton" @click="handleSubmit">
提 交
</view>
</view>
<view class="footer_container">
</view>
</template>
</BasicContainer>
<!-- 弹窗选择商品类型 -->
<MyDrawer ref="DrawerShowChooseTypeOfMerchandise">
<template #content>
<picker-view v-if="details.visible" :indicator-style="details.indicatorStyle" :immediate-change="true"
:value="details.value.Merchandise" @change="(e)=> bindChange(e,'Merchandise')" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item, index) in details.pickerArrObj.Merchandise" :key="index">
{{ item.label }}
</view>
</picker-view-column>
</picker-view>
</template>
</MyDrawer>
<!-- 弹窗选择商品类目 -->
<MyDrawer ref="DrawerShowChooseTypeOfGoodsCategory">
<template #content>
<picker-view v-if="details.visible" :indicator-style="details.indicatorStyle" :immediate-change="true"
:value="details.value.GoodsCategory" @change="(e)=> bindChange(e,'GoodsCategory')" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item, index) in details.pickerArrObj.GoodsCategory1" :key="index">
{{ item.label }}
</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item, index) in details.pickerArrObj.GoodsCategory2" :key="index">
{{ item.label }}
</view>
</picker-view-column>
</picker-view>
</template>
</MyDrawer>
<tips ref="tip"></tips>
</template>
<script setup lang="ts">
import { getCommonGoodsType, postInstallCommodityAdd, postInstallCommodityUpdate } from '@/api/user.js';
import { nextTick, reactive, ref, computed } from 'vue';
import utils from '@/utils/utils.js';
import {
onLoad,
onShow,
onHide,
onUnload
} from '@dcloudio/uni-app'
const option = reactive({
title: '添加信息',
haveData: true,
pageLoading: false,
haveReachBottom: false
})
const details = reactive({
isShow: false,
form: {
// 单位
unit: '',
// 产品名称
product_name: '',
// 数量
number: 0,
// 单价
price: 0,
// 总价
money: 0,
// 类型
Merchandise: '',
MerchandiseId: '',
// 类目
GoodsCategory: '',
GoodsCategoryId: [],
// 备注
remark: '',
// 商品id
id: ''
},
/** picker被选中的索引位置 */
value: { Merchandise: [0], GoodsCategory: [0, 0] },
/** picker行高度 */
indicatorStyle: `height: 40px;`,
visible: true,
pickerArrObj: {
Merchandise: [],
// 3级
GoodsCategory1: [],
// 4级
GoodsCategory2: []
},
goodsTypeArr: [],
pageInfo: {
type: 'add' as 'add' | 'edit',
/** 商品大类Id */
id: '',
/** 安装单ID */
install_id: ''
},
/** 图片list */
imgList: [] as { name : string, url : string }[]
})
// 组件实例
/** 选择商品类型 */
const DrawerShowChooseTypeOfMerchandise = ref()
/** 选择商品类目 */
const DrawerShowChooseTypeOfGoodsCategory = ref()
/** 弹窗 */
const tip = ref()
const initEditInfo = () => {
details.form = uni.getStorageSync('taskServersDetails')
console.log('details.form :>> ', details.form);
const {
commodity_type_ids,
images
} = details.form as any
const typeId = commodity_type_ids[1]
details.imgList = images
for (let i = 0; i < details.pickerArrObj.Merchandise.length; i++) {
const _value = details.pickerArrObj.Merchandise[i]
if (_value.value !== typeId) continue
details.form.Merchandise = _value.label || ''
details.form.MerchandiseId = _value.value || ''
details.value.Merchandise = [i]
details.pickerArrObj.GoodsCategory1 = _value.children || []
for (let j = 0; j < _value.children.length; j++) {
const _val = _value.children[j]
if (_val.value !== commodity_type_ids[2]) continue
details.form.GoodsCategory = _val.label
details.form.GoodsCategoryId = [_val.value]
details.value.GoodsCategory = [j]
details.pickerArrObj.GoodsCategory2 = (_val.children && _val.children) || []
}
if (commodity_type_ids.length !== 4) break
for (let j = 0; j < details.pickerArrObj.GoodsCategory2.length; j++) {
const _val = details.pickerArrObj.GoodsCategory2[j]
if (_val.value !== commodity_type_ids[3]) continue
details.form.GoodsCategory += ('/' + _val.label)
details.form.GoodsCategoryId[1] = _val.value
details.value.GoodsCategory[1] = j
}
break
}
console.log('details.pickerArrObj.Merchandise :>> ', details.pickerArrObj.Merchandise);
}
onLoad(async (e) => {
console.log('e :>> ', e);
const { type, id } = e
option.title = type === 'add' ? '添加信息' : '修改信息'
details.pageInfo = e
option.pageLoading = true
try {
option.pageLoading = true
await Promise.all([initGoodsTypeList(), initPage()])
// 编辑时初始化数据
type === 'edit' && initEditInfo()
} catch (err) {
console.log('err :>> ', err);
//TODO handle the exception
} finally {
option.pageLoading = false
}
})
onShow(() => {
})
onUnload(() => {
// 关闭后清除数据
uni.removeStorageSync('taskServersDetails')
})
const initPage = async () => {
if (details.pageInfo.type === 'add') return
}
/** 初始化获取goodsTypeList */
const initGoodsTypeList = async () => {
const res = await getCommonGoodsType({})
const { code, data } = res
if (code !== 200) return
details.goodsTypeArr = (data && data.CommodityTypeTree) || []
console.log('details.goodsTypeArr :>> ', details.goodsTypeArr);
for (let i = 0; i < details.goodsTypeArr.length; i++) {
const value = details.goodsTypeArr[i]
console.log((value.value + '') !== (details.pageInfo.id + ''))
if ((value.value + '') !== (details.pageInfo.id + '')) continue
console.log('value :>> ', value);
details.pickerArrObj.Merchandise = value.children
break
}
}
/** 关闭弹窗 */
const hidePopUp = (node) => {
details.visible = false
node.value.details.showPopUp = false
}
/** 显示商品类型选择弹窗 */
const handleShowChooseTypeOfMerchandise = () => {
details.visible = true
DrawerShowChooseTypeOfMerchandise.value.setDetails({
title: '请选择商品类型',
showPopUp: true,
height: '50vh',
success() {
try {
if (details.pickerArrObj.Merchandise.length === 0) return utils.handleToast('暂无可选类型')
const _item = details.pickerArrObj.Merchandise[(details.value.Merchandise || [0])[0]]
// 类型赋值
details.form.Merchandise = _item.label
details.form.MerchandiseId = _item.value
// 类目picker赋值
details.pickerArrObj.GoodsCategory1 = _item.children
details.pickerArrObj.GoodsCategory2 = _item.children[0].children || []
// 重置数据
details.form.GoodsCategory = ''
details.form.GoodsCategoryId = []
details.value.GoodsCategory = [0, 0]
} catch (err) {
console.log('err :>> ', err);
} finally {
hidePopUp(DrawerShowChooseTypeOfMerchandise)
}
},
close() {
hidePopUp(DrawerShowChooseTypeOfMerchandise)
}
})
}
/** 显示商品类目 */
const handleShowChooseTypeOfGoodsCategory = () => {
details.visible = true
DrawerShowChooseTypeOfGoodsCategory.value.setDetails({
showPopUp: true,
height: '50vh',
success() {
console.log('details.value.GoodsCategory :>> ', details.value.GoodsCategory);
try {
details.form.GoodsCategoryId = []
if (details.pickerArrObj.GoodsCategory1.length === 0) return utils.handleToast('暂无可选类型')
const _item1 = details.pickerArrObj.GoodsCategory1[(details.value.GoodsCategory || [0])[0]]
const _item2 = details.pickerArrObj.GoodsCategory2[(details.value.GoodsCategory || [0, 0])[1]]
console.log('_item1 :>> ', _item1);
console.log('_item2 :>> ', _item2);
if (!_item1) return
details.form.GoodsCategoryId[0] = _item1.value
details.form.GoodsCategory = _item1.label
details.form.price = _item1.price || 0
details.form.unit = _item1.unit || ''
if (!_item2) return
details.form.GoodsCategoryId[1] = _item2.value
details.form.GoodsCategory += ('/' + _item2.label)
details.form.price = _item2.price || 0
details.form.unit = _item2.unit || ''
} catch (err) {
console.log('err :>> ', err);
} finally {
hidePopUp(DrawerShowChooseTypeOfGoodsCategory)
}
},
close() {
hidePopUp(DrawerShowChooseTypeOfGoodsCategory)
}
})
}
/** picker切换时执行 */
const bindChange = function (e, type) {
console.log('type :>> ', type);
console.log('e :>> ', e);
if (type === 'GoodsCategory' && (e.detail.value[0] !== details.value.GoodsCategory[0])) {
console.log('111 :>> ', 111);
const _item = details.pickerArrObj.GoodsCategory1[e.detail.value[0]]
details.pickerArrObj.GoodsCategory2 = _item && _item.children ? _item.children : []
details.value.GoodsCategory = [e.detail.value[0], 0]
return
}
details.value[type] = e.detail.value
console.log('details.value :>> ', details.value);
}
/** 输入框输入值 -- 数量
* @param {Object} e 数据
* @param {string} type 数据
* @param {number} precision 精度
*/
const hadnleInputByNumber = async (e : object, type : string, precision = 0) => {
let value = e.detail.value + ''
const _valueArr = value.split('.')
const _secondNum = Number(_valueArr[1])
if (_secondNum) {
_valueArr[1] = (_secondNum + '').slice(0, precision)
}
if (precision > 0) value = _valueArr.slice(0, 2).join('.')
else value = _valueArr[0]
await nextTick()
details.form[type] = utils.isNumber(value) ? Number(value) : 0
}
/** 计算总费用 */
const handleComputedMoney = computed(() => {
const { number, price } = details.form
if (!utils.isNumber(number) || !utils.isNumber(price)) return 0
return utils.computeNumber(Number(number), '*', Number(price)).result
})
/** 上传文件 */
const handleUploadFile = () => {
const successByUpload = (res) => {
console.log('res :>> ', res);
const { data } = res
const _data = JSON.parse(data)
console.log('_data :>> ', _data);
const { code, data: img } = _data
details.imgList.push({ url: img, name: img })
}
utils.handleUploadFile({
successByUpload
})
}
/** 移除图片 */
const handleRmove = (index) => {
tip.value.setdetails({
isshow: true,
content: '确认移除',
cancelTxt: '取消',
confirmTxt: '确认',
success() {
details.imgList.splice(index, 1)
// 关闭弹窗
tip.value.setdetails({ isshow: false })
},
cancel() {
// 关闭弹窗
tip.value.setdetails({ isshow: false })
}
})
}
/** 新增提交 */
const addSubmit = async (submitData) => {
console.log('111 :>> ', 111);
return await postInstallCommodityAdd(submitData)
}
/** 编辑提交 */
const editSubmit = async (submitData) => {
console.log('222 :>> ', 222);
submitData.id = details.form.id
return await postInstallCommodityUpdate(submitData)
}
/** 提交 */
const handleSubmit = async () => {
console.log('22 :>> ', 22);
if (!details.form.GoodsCategory) return utils.handleToast('请选择类目')
if (!details.form.Merchandise) return utils.handleToast('请选择类型')
if (!details.form.product_name) return utils.handleToast('请输入产品名称')
if (!details.form.number) return utils.handleToast('请输入数量')
if (!details.form.price) return utils.handleToast('请输入单价')
console.log('11 :>> ', 11);
try {
option.pageLoading = true
const submitData : {
// 安装任务ID
install_id : string
// 商品类型,商品类型id集,树形类型每层得值
commodity_type_ids : string[]
// 单位
unit : string
// 产品名称
product_name : string
// 数量
number : number
// 单价
price : number
// 总价
money : number
// 备注
remark : string
// 图片合集
images : { name : string, url : string }[]
// 商品id
id ?: string
} = {
install_id: details.pageInfo.install_id,
commodity_type_ids: [details.pageInfo.id, details.form.MerchandiseId, ...details.form.GoodsCategoryId],
unit: details.form.unit,
product_name: details.form.product_name,
number: details.form.number,
price: details.form.price,
money: handleComputedMoney.value,
remark: details.form.remark,
images: details.imgList
}
const res = details.pageInfo.type === 'add' ? await addSubmit(submitData) : await editSubmit(submitData)
const { code, data } = res
if (code !== 200) return
uni.navigateBack()
} catch (err) {
console.log('err :>> ', err);
//TODO handle the exception
} finally {
option.pageLoading = false
}
}
</script>
<style scoped lang="scss">
@import url('@/utils/style/common.scss');
.server_container {
background: #fff;
:deep(.uni-input-placeholder) {
text-align: right;
}
:deep(.uni-input-input) {
text-align: right;
}
/* #ifdef MP-WEIXIN */
input {
text-align: right;
}
/* #endif */
}
.info_item_container {
padding: 20upx;
}
// 行
.row {
background: #fff;
// padding: 20upx;
border-bottom: 4upx solid #eee;
font-size: 0.9rem;
// min-height: 80upx;
&.border-none {
border: none;
}
.input {
height: 80upx;
:deep(.input_container) {
/* #ifdef MP-WEIXIN */
input {
text-align: right;
}
/* #endif */
}
}
.title {
font-weight: bold;
}
.info {
color: #999;
}
// 图片列表
.imgList {
.image_conatiner {
position: relative;
.removeIcon {
position: absolute;
top: 0;
right: 0;
transform: translate(40%, -40%);
opacity: 0.9;
}
}
.addImg {
width: 160upx;
height: 160upx;
border-radius: 20upx;
box-sizing: border-box;
border: 2upx solid #eee;
}
image {
width: 160upx;
height: 160upx;
border-radius: 20upx;
}
}
:deep(.messageBox) {
right: 20upx;
}
}
// 提交按钮
.submitButton {
width: 80%;
text-align: center;
padding: 20upx;
background: var(--subjectColor);
color: #fff;
border-radius: 60upx;
position: fixed;
bottom: 60upx;
left: 50%;
transform: translateX(-50%);
}
// 底部站位
.footer_container {
height: 140upx;
}
</style>