chenrui 3 år sedan
förälder
incheckning
4872d6967d

+ 18 - 0
api/sales.js

@@ -61,6 +61,24 @@ export const salesDetailDel = (params) => {
     method: 'get'
   })
 }
+//  仓库列表  无分页
+export const warehouseAllList = (params) => {
+  const url = 'warehouse/queryList'
+  return axios.request({
+    url: url,
+    data: params,
+    method: 'post'
+  })
+}
+// 车架号  识别图片内容
+export const vinCodeParse = params => {
+  return axios.request({
+    url: `vinIdentify/ocr`,
+    method: 'post',
+    data: params,
+    responseType: 'blob'
+  })
+}
 
 // 产品报价列表
 export const dealerProductList = (params) => {

+ 9 - 0
pages.json

@@ -216,6 +216,15 @@
 				"enablePullDownRefresh": false
 			}
 		},
+		{
+			"path": "pages/sales/chooseProduct", // 选择产品
+			"style": {
+				"navigationBarTitleText": "选择产品",
+				"enablePullDownRefresh": false,
+				"navigationStyle":"custom",
+				"navigationBarTextStyle": "white"
+			}
+		},
 		{
 			"path": "pages/sales/chooseCustomer", // 销售单  选择客户
 			"style": {

+ 112 - 0
pages/sales/chooseProduct.vue

@@ -0,0 +1,112 @@
+<template>
+	<view class="chooseProduct-wrap">
+		<!-- 标题 -->
+		<u-navbar title="选择产品" :safeAreaInsetTop="false" :border-bottom="true">
+			<view class="u-nav-slot" slot="right" style="padding-right: 30rpx;">
+				<u-icon name="search" color="#999" size="28" @click="openModal=true"></u-icon>查询
+			</view>
+		</u-navbar>
+		<!-- 产品列表 -->
+		<view class="product-list-box">
+			<scroll-view class="sales-list-con" :style="{height: scrollH+'upx'}" scroll-y @scrolltolower="onreachBottom">
+				<view class="sales-list-item border-b font_13 flex justify_between" v-for="(item, index) in listData" :key="item.id">
+					<view class="pimgs">
+						<u-image :src="item.productMainMsg?item.productMainMsg:`../../static/${theme}/def_img@2x.png`" width="128" height="128" border-radius="10"></u-image>
+						<view v-if="item.oosFlag == 1" class="sign" :style="{backgroundColor: $config('errorColor')}">急</view>
+						<view v-if="item.price < item.cost" class="sign" :style="{backgroundColor: $config('errorColor')}">亏</view>
+						<view v-if="item.price == 0" class="sign" :style="{backgroundColor: $config('errorColor')}">赠</view>
+					</view>
+					<view class="sales-item-main flex_1">
+						<view class="sales-item-name">{{item.productName || '--'}}</view>
+						<view class="sales-item-txt flex align_center justify_between">
+							<view>{{item.productCode || '--'}}</view>
+							<u-icon v-if="pageData.type=='edit'" @click="handleDel(item)" name="trash-fill" :color="$config('errorColor')" size="34"></u-icon>
+						</view>
+						<view class="sales-item-txt color_6" style="font-size: 24upx;" v-if="item.warehouseEntity&&item.warehouseEntity.name || item.warehouseLocationEntity&&item.warehouseLocationEntity.name">{{item.warehouseEntity&&item.warehouseEntity.name}} > {{item.warehouseLocationEntity&&item.warehouseLocationEntity.name}}</view>
+						<view class="sales-item-txt flex align_center justify_between">
+							<view class="sales-item-priceInfo">
+								<view :style="{color: $config('errorColor'), display: 'inline-block'}">¥<text style="font-size: 30upx;">{{toThousands(item.price||0, 2)}}</text></view>
+								<text style="display: inline-block;margin: 0 10upx;">*</text> 
+								<text style="font-size: 30upx;">{{toThousands(item.qty||0)}}</text>
+								{{item.productUnit}}
+							</view>
+							<view class="sales-item-price">¥{{toThousands(item.totalAmount||0, 2)}}</view>
+						</view>
+						<view class="sales-item-price">折后¥{{toThousands(item.discountedAmount||0, 2)}}</view>
+					</view>
+				</view>
+				<view v-if="listData && listData.length == 0">
+					<u-empty :text="noDataText" mode="list" :img-width="200" :margin-top="30"></u-empty>
+				</view>
+			</scroll-view>
+		</view>
+		<!-- 查询右侧弹框 -->
+		<productSearch :openModal="openModal" :defaultParams="searchForm" @refresh="refresh" @close="openModal=false" />
+	</view>
+</template>
+
+<script>
+	import ProductSearch from './productSearch.vue'
+	import { toThousands } from '@/libs/tools'
+	export default{
+		components: { ProductSearch },
+		data(){
+			return{
+				toThousands,
+				customBtnStyle: {  //  自定义按钮样式
+					borderColor: this.$config('primaryColor'),
+					backgroundColor: this.$config('primaryColor'),
+					color: '#fff'
+				},
+				listData: [],
+				pageNo: 1,
+				pageSize: 6,
+				totalNum: 0,
+				noDataText: '暂无数据',
+				searchForm: {},
+				searchParams: {},
+				openModal: false,
+				theme: '',
+				chooseProductList: [],
+				scrollH: 0,
+			}
+		},
+		onLoad(opt) {
+			this.theme = getApp().globalData.theme
+			if(opt){
+				this.chooseProductList = opt.data ? JSON.parse(opt.data) : null
+			}
+			console.log(this.chooseProductList)
+			this.getList()
+			
+			const _this = this
+			let footerH = _this.$refs.productTotal && _this.$refs.productTotal.$el && _this.$refs.productTotal.$el.offsetHeight || 0
+			uni.getSystemInfo({
+				success: function (res) {
+					const winH = res.windowHeight * 2
+					_this.scrollH = winH - footerH - 85
+				}
+			})
+		},
+		methods: {
+			// 获取查询参数 刷新列表
+			refresh(params){
+				const _this = this
+				this.searchParams = Object.assign(params, this.searchForm)
+				this.$nextTick(function(){
+					// _this.$refs.salesList.getList(1)
+				})
+			},
+			getList(){}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.chooseProduct-wrap{
+		width: 100%;
+		.list-box{
+			padding: 20upx 20upx;
+		}
+	}
+</style>

+ 5 - 1
pages/sales/edit.vue

@@ -23,7 +23,7 @@
 								打折
 								<text v-if="discountAmount">:¥{{discountAmount}}</text>
 							</u-button>
-							<u-button @click="" size="mini" :hair-line="false" plain type="primary" hover-class="none">选择产品</u-button>
+							<u-button @click="handleProduct" size="mini" :hair-line="false" plain type="primary" hover-class="none">选择产品</u-button>
 						</view>
 					</template>
 				</u-section>
@@ -229,6 +229,10 @@
 					}
 				})
 			},
+			// 选择产品
+			handleProduct(){
+				uni.navigateTo({ url: '/pages/sales/chooseProduct?data='+JSON.stringify(this.listData) })
+			},
 			changeScrollH(){
 				const _this = this
 				uni.getSystemInfo({

+ 3 - 4
pages/sales/index.vue

@@ -26,10 +26,10 @@
 				<u-image class="nav-pic" style="margin-top: 5upx;" :src="`../../static/${theme}/navIcon/price_icon.png`" width="60" height="60"></u-image>
 				<text class="nav-txt" style="margin-top: 5upx;">产品报价</text>
 			</view>
-			<!-- <view class="nav-item" @click="toPage('/pages/sales/chooseCustomer')">
+			<view class="nav-item" @click="toPage('/pages/sales/chooseCustomer')">
 				<u-image class="nav-pic" :src="`../../static/${theme}/navIcon/sale_icon.png`" width="70" height="70"></u-image>
 				<text class="nav-txt">新增销售单</text>
-			</view> -->
+			</view>
 		</view>
 		<!-- 销售单 -->
 		<view class="sales-list">
@@ -183,8 +183,7 @@
 		}
 		.nav-cont{
 			.nav-item{
-				// width: 49%;
-				width: 100%;
+				width: 49%;
 				border-radius: 25upx;
 				background-color: #ffffff;
 				padding: 14upx 0;

+ 1 - 1
pages/sales/list.vue

@@ -2,7 +2,7 @@
 	<view class="sales-list-wrap">
 		<!-- 标题 -->
 		<u-navbar title="销售单" :safeAreaInsetTop="false" :border-bottom="true">
-			<view class="u-nav-slot" slot="right" style="padding-right: 20rpx;">
+			<view class="u-nav-slot" slot="right" style="padding-right: 30rpx;">
 				<u-icon name="search" color="#999" size="28" @click="openModal=true"></u-icon>查询
 			</view>
 		</u-navbar>

+ 4 - 4
pages/sales/listComponent.vue

@@ -25,14 +25,14 @@
 							<view class="flex_1">收款方式:<text>{{item.settleStyleEntity&&item.settleStyleEntity.name||'--'}}</text></view>
 						</view>
 					</view>
-					<!-- <view class="button-box">
+					<view class="button-box">
 						<u-button @click="handleFun('audit', item)" size="mini" :hair-line="false" plain type="primary" hover-class="none" v-if="item.billStatus == 'WAIT_AUDIT'">审核</u-button>
 						<u-button @click="handleFun('out', item)" size="mini" :hair-line="false" plain type="primary" hover-class="none" v-if="item.billStatus == 'WAIT_OUT_WAREHOUSE'">出库</u-button>
 						<u-button @click="handleEdit(item)" size="mini" :hair-line="false" plain type="primary" hover-class="none" v-if="((item.salesBillSource == 'SATELLITE' || item.salesBillSource == 'SALES') && (item.billStatus == 'WAIT_AUDIT' || item.billStatus == 'WAIT_SUBMIT' || item.billStatus == 'AUDIT_REJECT'))">编辑</u-button>
 						<u-button @click="handleFun('del', item)" size="mini" :hair-line="false" plain type="primary" hover-class="none" v-if="((item.salesBillSource == 'SATELLITE' || item.salesBillSource == 'SALES') && item.billStatus != 'FINISH')">删除</u-button>
 						<u-button @click="handleEdit(item)" size="mini" :hair-line="false" plain type="primary" hover-class="none" v-if="(item.salesBillSource == 'PURCHASE' && (item.billStatus == 'WAIT_AUDIT' || item.billStatus == 'SUPERIOR_CHANGE'))">改单</u-button>
 						<u-button @click="handleFun('cancel', item)" size="mini" :hair-line="false" plain type="primary" hover-class="none" v-if="(item.salesBillSource == 'PURCHASE' && (item.billStatus == 'WAIT_AUDIT' || item.billStatus == 'SUPERIOR_CHANGE'))">取消</u-button>
-					</view> -->
+					</view>
 				</view>
 				<view v-if="listData && listData.length == 0">
 					<u-empty :text="noDataText" mode="list" :img-width="200" :margin-top="30"></u-empty>
@@ -85,10 +85,10 @@
 		mounted() {
 			const _this = this
 			uni.getSystemInfo({
-			    success: function (res) {
+				success: function (res) {
 					const winH = res.windowHeight * 2
 					_this.scrollH = winH - _this.height - 85
-			    }
+				}
 			})
 			this.getList()
 		},

+ 296 - 0
pages/sales/productSearch.vue

@@ -0,0 +1,296 @@
+<template>
+	<view class="productSearch-wrap">
+		<u-popup v-model="isShow" class="search-popup" mode="right" @close="isShow=false" length="85%">
+			<view class="search-title">筛选</view>
+			<u-form class="form-content" :model="form" ref="uForm" label-width="180">
+				<u-form-item label="车架号(VIN)" prop="productCode" class="form-item">
+					<u-input v-model.trim="form.productCode" :maxlength="17" placeholder="请输入车架号" input-align="right" />
+					<u-icon @click="uploadFun" :name="vinLoading?'loading':'camera-fill'" name="camera-fill" color="#c8c0cc" size="34" style="margin-left: 14upx;"></u-icon>
+					<!-- <u-upload ref="uUpload" :custom-btn="true" :action="action" :form-data="{savePathType: 'local'}" @on-success="uploadSuccess" :max-size="2 * 1024 * 1024" max-count="1">
+						<view slot="addBtn" class="slot-btn" hover-class="slot-btn__hover" hover-stay-time="150">
+							<u-icon name="camera-fill" color="#c8c0cc" size="34" style="margin-left: 14upx;"></u-icon>
+						</view>
+					</u-upload> -->
+				</u-form-item>
+				<u-form-item label="产品编码" prop="productCode" class="form-item">
+					<u-input v-model.trim="form.productCode" placeholder="请输入产品编码" input-align="right" />
+				</u-form-item>
+				<u-form-item label="原厂编码" prop="productOrigCode" class="form-item">
+					<u-input v-model.trim="form.productOrigCode" placeholder="请输入原厂编码" input-align="right" />
+				</u-form-item>
+				<u-form-item label="产品名称" prop="productName" class="form-item">
+					<u-input v-model.trim="form.productName" placeholder="请输入产品名称" input-align="right" />
+				</u-form-item>
+				<u-form-item label="产品品牌" prop="productBrandSn" class="form-item">
+					<u-input v-model="brandName" @click="brandModal=true" disabled placeholder="请选择产品品牌" input-align="right" />
+				</u-form-item>
+				<u-form-item label="产品分类" prop="productTypeSn" class="form-item">
+					<u-input v-model="productTypeNameArr" @click="showTypeModal=true" disabled placeholder="请选择产品分类" input-align="right" />
+				</u-form-item>
+				<u-form-item label="仓库" prop="warehouseSn" class="form-item">
+					<u-input v-model="warehouseName" @click="warehouseModal=true" disabled placeholder="请选择仓库" class="form-item-inp" input-align="right" />
+					<u-icon v-show="warehouseName.length != 0" name="close-circle-fill" color="#c8c0cc" size="32" class="close-circle" @click="clearWarehouse"></u-icon>
+				</u-form-item>
+				<u-form-item label="成本价">
+					<u-switch slot="right" v-model="cost"></u-switch>
+				</u-form-item>
+				<u-form-item label="市级价">
+					<u-switch slot="right" v-model="cityPrice"></u-switch>
+				</u-form-item>
+			</u-form>
+			<view class="uni-list-btns">
+				<u-button class="handle-btn" size="medium" hover-class="none" @click="resetForm">重置</u-button>
+				<u-button class="handle-btn search-btn" size="medium" hover-class="none" :custom-style="customBtnStyle" @click="handleSearch">查询</u-button>
+			</view>
+		</u-popup>
+		<!-- 产品品牌 -->
+		<productBrand :openModal="brandModal" :itemSn="form.productBrandSn" @choose="brandChoose" @clean="brandClean" @close="brandModal=false" />
+		<!-- 产品分类 -->
+		<productType :openModal="showTypeModal" :nowData="nowData" @choose="typeChoose" @clean="typeClean" @close="showTypeModal=false" />
+		<!-- 选择收款方式 -->
+		<u-picker v-model="warehouseModal" @confirm="warehouseChange" :range="warehouseList" range-key="name" mode="selector"></u-picker>
+		<input type="file" id="filed" accept="image/jpeg,image/png" hidden="" @change="filePreview">
+	</view>
+</template>
+
+<script>
+	import productBrand from '@/pages/common/productBrand.vue'
+	import productType from '@/pages/common/productType.vue'
+	import { warehouseAllList, vinCodeParse } from '@/api/sales'
+	const baseUrl = getApp().globalData.baseUrl
+	export default{
+		components: { productBrand, productType },
+		props: {
+			openModal: { //  弹框显示状态
+				type: Boolean,
+				default: false
+			},
+			defaultParams: {  //  默认筛选条件
+				type: Object,
+				default: () => {
+					return {}
+				}
+			}
+		},
+		data(){
+			return{
+				isShow: this.openModal,
+				form: {
+					vinCode: '',
+					productCode: '', //  产品编码
+					productName: '', //  产品名称
+					productOrigCode: '', //  原厂编码
+					productBrandSn: undefined, //  产品品牌
+					productTypeSn1: undefined, //  产品分类1
+					productTypeSn2: undefined, //  产品分类2
+					productTypeSn3: undefined, //  产品分类3
+					warehouseSn: undefined //  仓库
+				},
+				cost: false,  // 成本价
+				cityPrice: false,  // 市级价
+				customBtnStyle: {  //  自定义按钮样式
+					borderColor: this.$config('primaryColor'),
+					backgroundColor: this.$config('primaryColor'),
+					color: '#fff'
+				},
+				warehouseName: '',
+				warehouseModal: false,
+				warehouseList: [],
+				brandModal: false,
+				brandName: '',
+				showTypeModal: false,
+				nowData: {
+					data: [],
+					indArr: [],
+					nowInd: 0
+				},
+				vinLoading: false,
+			}
+		},
+		computed: {
+			productTypeNameArr: function() {
+				let str = ''
+				this.nowData.data.map(item => {
+					str += item.productTypeName+' / '
+				})
+				return str ? str.substr(0, str.length-3) : ''
+			}
+		},
+		mounted() {
+			this.init()
+			this.getWarehouse()
+		},
+		methods: {
+			//  初始化数据
+			init(){
+				// if(this.defaultParams.beginDate && this.defaultParams.endDate){
+				// 	this.form.date = this.defaultParams.beginDate + ' ~ ' + this.defaultParams.endDate
+				// }else{
+				// 	this.form.date = ''
+				// }
+				// this.beginDate = this.defaultParams.beginDate ? this.defaultParams.beginDate : ''
+				// this.endDate = this.defaultParams.endDate ? this.defaultParams.endDate : ''
+				// this.form.buyerName = this.defaultParams.buyerName ? this.defaultParams.buyerName : ''
+				// this.form.salesBillNo = this.defaultParams.salesBillNo ? this.defaultParams.salesBillNo : ''
+				// this.form.purchaseBillNo = this.defaultParams.purchaseBillNo ? this.defaultParams.purchaseBillNo : ''
+				// this.form.warehouseSn = this.defaultParams.warehouseSn ? this.defaultParams.warehouseSn : ''
+			},
+			// 查询
+			handleSearch() {
+				let params = JSON.parse(JSON.stringify(this.form))
+				delete params.date
+				this.$emit('refresh', params)
+				this.isShow = false
+			},
+			// 重置
+			resetForm() {
+				this.warehouseName = ''
+				this.form.beginDate = ''
+				this.form.endDate = ''
+				this.$refs.uForm.resetFields()
+				this.$emit('refresh', {})
+				this.isShow = false
+			},
+			uploadFun () {
+				console.log(111,document.getElementById('filed'))
+				document.getElementById('filed').click()
+				console.log(333)
+			},
+			filePreview (e) {
+				console.log(222)
+				const _this = this
+				var files = e.target.files[0]
+				const formData = new FormData()
+				formData.append('savePathType', 'local')
+				formData.append('file', files)
+				this.vinLoading = true
+				vinCodeParse(formData).then(res => {
+					if (res.type == 'application/json') {
+						var reader = new FileReader()
+						reader.addEventListener('loadend', function () {
+						const obj = JSON.parse(reader.result)
+						if (obj.status == 200) {
+							_this.form.vinCode = obj.data || ''
+							// 移除表单项的校验结果
+							// _this.$refs.uForm.clearValidate('vinCode')
+						} else {
+							this.toashMsg(obj.message)
+						}
+						_this.vinLoading = false
+						document.getElementById('filed').value = ''
+					})
+					reader.readAsText(res)
+			    } else {
+					_this.vinLoading = false
+			    }
+			  })
+			},
+			// 选择品牌
+			brandChoose(data){
+				this.brandName = data.brandName
+				this.form.productBrandSn = data.brandSn
+			},
+			// 清空品牌
+			brandClean(){
+				this.brandName = ''
+				this.form.productBrandSn = undefined
+			},
+			// 选择分类
+			typeChoose(obj){
+				this.nowData = {
+					data: obj.data,
+					indArr: obj.indArr,
+					nowInd: obj.nowInd
+				}
+				this.form.productTypeSn1 = this.nowData.data[0]&&this.nowData.data[0].productTypeSn ? this.nowData.data[0].productTypeSn : undefined
+				this.form.productTypeSn2 = this.nowData.data[1]&&this.nowData.data[1].productTypeSn ? this.nowData.data[1].productTypeSn : undefined
+				this.form.productTypeSn3 = this.nowData.data[2]&&this.nowData.data[2].productTypeSn ? this.nowData.data[2].productTypeSn : undefined
+			},
+			// 清空分类
+			typeClean(){
+				this.nowData = {
+					data: [],
+					indArr: [],
+					nowInd: 0
+				}
+				this.form.productTypeSn1 = undefined
+				this.form.productTypeSn2 = undefined
+				this.form.productTypeSn3 = undefined
+			},
+			//  清空仓库
+			clearWarehouse(){
+				this.warehouseName = ''
+				this.form.warehouseSn = undefined
+			},
+			// 仓库  change
+			warehouseChange(ind){
+				this.form.warehouseSn = this.warehouseList[ind].warehouseSn || undefined
+				this.warehouseName = this.warehouseList[ind].name || ''
+			},
+			// 仓库列表
+			getWarehouse () {
+				warehouseAllList().then(res => {
+					if(res.status == 200 && res.data){
+						this.warehouseList = res.data
+						// 仓库有值时,匹配对应name
+						if(this.defaultParams.warehouseSn || this.defaultParams.warehouseSn==0){
+							this.warehouseList.map(item => {
+								if(item.warehouseSn == this.defaultParams.warehouseSn){
+									this.warehouseName = item.name
+								}
+							})
+						}
+					}else{
+						this.warehouseList = []
+					}
+				})
+			},
+		},
+		watch: {
+			//  父页面传过来的弹框状态
+			openModal (newValue, oldValue) {
+				this.isShow = newValue
+			},
+			//  重定义的弹框状态
+			isShow (newValue, oldValue) {
+				if (!newValue) {
+					this.$emit('close')
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.productSearch-wrap{
+		.search-popup {
+			.search-title {
+				text-align: center;
+				padding: 30upx 22upx;
+				color: #333;
+				border-bottom: 1px solid #eee;
+			}
+			.form-content {
+				display: block;
+				padding: 0 20upx;
+				box-sizing: content-box;
+				.form-item-inp{
+					display: inline-block;
+					width: 88%;
+					vertical-align: top;
+				}
+			}
+			.uni-list-btns {
+				display: flex;
+				padding: 20upx;
+				margin-top: 100upx;
+				.handle-btn {
+					font-size: 28upx;
+					margin: 0 30upx;
+					width: 100%;
+					flex: 1;
+				}
+			}
+		}
+	}
+</style>

+ 1 - 1
pages/sales/salesSearch.vue

@@ -167,7 +167,7 @@
 		.search-popup {
 			.search-title {
 				text-align: center;
-				padding: 18upx 22upx;
+				padding: 30upx 22upx;
 				color: #333;
 				border-bottom: 1px solid #eee;
 			}