Browse Source

feat:线下订单

Moss 1 year ago
parent
commit
486e36cc6f
2 changed files with 559 additions and 46 deletions
  1. 18 0
      src/api/order.js
  2. 541 46
      src/views/mallManagement/order/offline_order_list/index.vue

+ 18 - 0
src/api/order.js

@@ -223,4 +223,22 @@ export function offlineOrderListExport(data, name) {
     data,
     name
   })
+}
+
+// 线下订单保存
+export function offlineOrderSave(params) {
+  return request({
+    url: '/order/offline/save',
+    method: 'post',
+    data: params
+  })
+}
+
+// 新增标签
+export function getOfflineOrderDetail(params) {
+  return request({
+    url: '/order/offline/detail',
+    method: 'post',
+    params
+  })
 }

+ 541 - 46
src/views/mallManagement/order/offline_order_list/index.vue

@@ -4,33 +4,243 @@
 			<template-page v-if="activeKey == 'list'" ref="pageRef" :get-list="getList" :table-attributes="tableAttributes" :table-events="tableEvents"
 			  :options-evens-group="optionsEvensGroup" :moreParameters="moreParameters" :column-parsing="columnParsing"
 			  :operation="operation()" :exportList="exportList">
+        <div slot="moreSearch">
+          <el-radio-group v-model="examineStatus" size="mini" @change="changeType">
+            <el-radio-button label="">全部</el-radio-button>
+            <el-radio-button label="WAIT">待审核</el-radio-button>
+            <el-radio-button label="OK">审核通过</el-radio-button>
+            <el-radio-button label="FAIL">审核驳回</el-radio-button>
+          </el-radio-group>
+          <br><br>
+        </div>
 			</template-page>
-			<div v-if="~['add', 'edit'].indexOf(activeKey)">
-				<zj-form-container ref="formRef" :form-data="formData" :styleSwitch="false">
-				  <zj-form-module title="" label-width="100px" :showPackUp="false"
-				    :form-data="formData" :form-items="formItems">
-				  </zj-form-module>
-				</zj-form-container>
-				<div slot="footer" class="dialog-footer">
+			<div v-if="~['add', 'edit'].indexOf(activeKey)" style="box-sizing: border-box;padding: 16px;">
+
+				<el-form ref="formRef" :model="formData" :rules="formRules" label-position="left" label-width="90px">
+
+          <div style="font-weight: 500;">客户信息</div>
+          <el-divider></el-divider>
+
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <el-form-item label="业务员" prop="saleName">
+                <el-input v-model="formData.saleName" autocomplete="off" placeholder="请输入业务员"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="业务员电话" prop="saleMobile">
+                <el-input v-model="formData.saleMobile" autocomplete="off" placeholder="请输入业务员电话"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="销售类型" prop="salesType">
+                <el-radio-group v-model="formData.salesType" disabled>
+                  <el-radio :label="''">线下销售</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="客户名称" prop="receUserName">
+                <el-input v-model="formData.receUserName" autocomplete="off" placeholder="请输入客户名称"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="客户电话" prop="recePhone">
+                <el-input v-model="formData.recePhone" autocomplete="off" placeholder="请输入客户电话"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="支付方式" prop="payType">
+                <el-radio-group v-model="formData.payType">
+                  <el-radio label="WECHAT">微信支付</el-radio>
+                  <el-radio label="CASH">现金支付</el-radio>
+                  <el-radio label="TRANSFER">转账支付</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="24">
+              <el-form-item label="客户地址" prop="province" :required="true">
+                <el-row>
+                  <el-col :span="5" style="margin-right: 12px;">
+                    <el-input type="text" v-model="formData.province" disabled placeholder="请选择省"></el-input>
+                  </el-col>
+                  <el-col :span="5" style="margin-right: 12px;">
+                    <el-input type="text" v-model="formData.city" disabled placeholder="请选择市"></el-input>
+                  </el-col>
+                  <el-col :span="5" style="margin-right: 12px;">
+                    <el-input type="text" v-model="formData.area" disabled placeholder="请选择区"></el-input>
+                  </el-col>
+                  <el-col :span="8">
+                    <el-input type="text" v-model="formData.street" disabled placeholder="请选择街道"></el-input>
+                  </el-col>
+                </el-row>
+              </el-form-item>
+            </el-col>
+            <el-col :span="24">
+              <el-form-item label="" prop="receAddress">
+                <el-row :gutter="20">
+                  <el-col :span="22">
+                    <el-input type="text" v-model="formData.receAddress" placeholder="详细地址"></el-input>
+                  </el-col>
+                  <el-col :span="2">
+                    <geographicalPosi :formData="formData" @selectPosi="selectAddress"/>
+                  </el-col>
+                </el-row>
+              </el-form-item>
+            </el-col>
+            <el-col :span="24">
+              <el-form-item label="备注" prop="remark">
+                <el-input type="textarea" v-model="formData.remark" autocomplete="off" placeholder="请输入备注"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="24">
+              <el-form-item label="附件" prop="remark">
+                <el-upload class="avatar-uploader" style="height:122px" :action="baseURL + 'common/upload'" :headers="myHeaders"
+                  :show-file-list="false" :on-success="uploadSuccess" :before-upload="beforeUpload">
+                  <img v-if="formData.fileUrl" :src="formData.fileUrl" class="avatar">
+                  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+                </el-upload>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <div style="font-weight: 500;">商品信息</div>
+          <el-divider></el-divider>
+
+          <div>
+            <el-button type="primary" size="small" @click="addGoods">添加</el-button>
+          </div>
+          <el-table
+            class="specTable"
+            :data="goodsList"
+            element-loading-text="Loading"
+            border
+            highlight-current-row
+            stripe
+            style="margin-top: 20px">
+            <el-table-column align="center" label="品牌" prop="brandName" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.brandName}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="大类" prop="mainName" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.mainName}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="小类" prop="smallName" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.smallName}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="商品名称" prop="goodsName" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.goodsName}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="规格型号" prop="goodsMaterialId" min-width="120">
+              <template slot-scope="scope">
+                <el-select size="small" v-model="scope.row.goodsMaterialId" filterable placeholder="请选择" @change="changeSpec(scope.$index, scope.row)">
+                  <el-option
+                    v-for="item in goodsSpecList"
+                    :key="item.id"
+                    :label="item.specsName"
+                    :value="item.id">
+                  </el-option>
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="单位" prop="unit" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.unit | unitFilter}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="订单数量" prop="num" min-width="120">
+              <template slot-scope="scope">
+                <el-input size="small" v-model="scope.row.num"></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="内机数量" prop="insideQty" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.insideQty}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="外机数量" prop="outQty" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.outQty}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="配件数量" prop="partsQty" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.partsQty}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="单价" prop="price" min-width="120">
+              <template slot-scope="scope">
+                <el-input size="small" v-model="scope.row.price"></el-input>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="金额" prop="amount" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.amount}}
+              </template>
+            </el-table-column>
+            <el-table-column align="center" label="库存数量" prop="stockQty" min-width="120">
+              <template slot-scope="scope">
+                {{scope.row.stockQty}}
+              </template>
+            </el-table-column>
+
+            <el-table-column align="center" label="操作" min-width="120">
+              <template slot-scope="scope">
+                <!-- <el-button type="text" @click="edit('theory', scope.$index)">编辑</el-button> -->
+                <el-popconfirm title="确定删除吗?" @confirm="deleteGoods(scope.$index)" style="margin-left: 10px;">
+                  <el-button slot="reference" type="text">删除</el-button>
+                </el-popconfirm>
+              </template>
+            </el-table-column>
+          </el-table>
+          
+        </el-form>
+				<div slot="footer" class="dialog-footer" style="margin-top: 20px;">
 				  <el-button size="mini" @click="data.removeTab()">取 消</el-button>
 				  <el-button size="mini" @click="formConfirm(data.removeTab)" type="primary">确 定</el-button>
 				</div>
 			</div>
+
+      <div v-if="~['detail', 'examine'].indexOf(activeKey)" style="box-sizing: border-box;padding: 16px;">
+        
+      </div>
 		</template>
 	</zj-tab-page>
 </template>
 
 <script>
+import { getToken } from '@/utils/auth'
+import { lbsAmapRegion } from '@/api/common.js'
 import TemplatePage from '@/components/template/template-page-1.vue'
 import import_mixin from '@/components/template/import_mixin.js'
 import { required, mobileRequired, mobile } from '@/components/template/rules_verify.js'
-import { getOfflineOrderList, offlineOrderListExport } from "@/api/order";
+import { getOfflineOrderList, offlineOrderListExport, offlineOrderSave, getOfflineOrderDetail } from "@/api/order";
+import { getGoodsSpecList } from '@/api/goods'
 import operation_mixin from '@/components/template/operation_mixin.js'
+import geographicalPosi from '@/components/geographicalPosi/index.vue'
 export default {
-  components: { TemplatePage },
+  components: { TemplatePage, geographicalPosi },
   mixins: [import_mixin,operation_mixin],
+  filters: {
+    unitFilter(val) {
+      const MAP = {
+        C: '整套',
+        I: '单个'
+      }
+      return MAP[val];
+    }
+  },
   data() {
     return {
+      baseURL: process.env.VUE_APP_BASE_API,
+      myHeaders: { 'x-token': getToken() },
       // 表格属性
       tableAttributes: {
         // 启用勾选列
@@ -47,10 +257,43 @@ export default {
       formDialogTitles: ["新增", "编辑"],
       formDialog: false,
       formData: {
-        remark: '',
+        saleName: '', // 业务员
+        saleMobile: '', // 业务员电话
+        salesType: '', // 销售类型
+        receUserName: '', // 客户名称
+        recePhone: '', // 客户电话
+        payType: 'WECHAT', // 支付方式
+        lng: '',
+        lat: '',
+        province: '',
+        provinceId: '',
+        city: '',
+        cityId: '',
+        area: '',
+        areaId: '',
+        street: '',
+        streetId: '',
+        receAddress: '',
+        remark: '', // 备注
+        fileUrl: '', // 附件
       },
-		formType: 'add',
-		formVisible: false,
+      formRules: {
+        receUserName: [{ required: true, message: '请输入客户名称', trigger: 'blur' }],
+        recePhone: [{ required: true, message: '请输入客户电话', trigger: 'blur' }],
+        payType: [{ required: true, message: '请选择支付方式', trigger: 'change' }],
+      },
+      formType: 'add',
+      formVisible: false,
+
+      examineStatus: '',
+      provinceList: [],
+      cityList: [],
+      areaList: [],
+      streetList: [],
+      goodsList: [],
+      goodsSpecList: [],
+
+      detailData: {},
     }
   },
   computed: {
@@ -86,9 +329,25 @@ export default {
       }]
     }
   },
+
+  create() {
+		
+  },
+
   methods: {
     // 列表请求函数
-    getList: getOfflineOrderList,
+    // getList: getOfflineOrderList,
+    getList(p) {
+      try {
+        var pam = JSON.parse(JSON.stringify(p))
+        if (this.examineStatus) {
+          pam.params.push({ "param": "a.examine_status", "compare": "=", "value": this.examineStatus })
+        }
+        return getOfflineOrderList(pam)
+      } catch (error) {
+        console.log(error)
+      }
+    },
     // 列表导出函数
     exportList: offlineOrderListExport,
     // 表格列解析渲染数据更改
@@ -99,53 +358,66 @@ export default {
     selectionChange(data) {
       this.recordSelected = data
     },
-	// 表格操作列
-	operation() {
-		return this.operationBtn({
-			remark: {
-				btnType: 'text',
-				click: ({ row, index, column }) => {
-					Object.assign(this.formData, row)
-					this.formDialogType = 0
-					this.openForm('remark',row)
-				}
-			},
-			account: {
-				conditions: ({ row, index, column }) => {
-					return row.orderStatus === 'OVER' && ~["EXCEPTION", "ING"].indexOf(row.status)
-				},
-				btnType: 'text',
-				prompt: '是否确定结算?',
-					click: ({ row, index, column }) => {
-						settlement({
-							orderId: row.orderId
-						}).then(res => {
-							this.$message({ type: 'success', message: `结算成功!` })
-							this.$refs.pageRef.refreshList()
-						})
-					}
-				},
-		})
-	},
-    openForm(type) {
+    // 切换状态
+    changeType(val) {
+      this.$refs.pageRef.refreshList()
+    },
+    // 表格操作列
+    operation() {
+      return this.operationBtn({
+        edit: {
+          btnType: 'text',
+          click: ({ row, index, column }) => {
+            this.openForm('edit', row.orderId)
+          }
+        },
+        detail: {
+          btnType: 'text',
+          click: ({ row, index, column }) => {
+            this.openDetail('detail', row.orderId)
+          }
+        },
+        examine: {
+          // conditions: ({ row, index, column }) => {
+          //   return row.orderStatus === 'OVER' && ~["EXCEPTION", "ING"].indexOf(row.status)
+          // },
+          btnType: 'text',
+          click: ({ row, index, column }) => {
+            this.openDetail('examine', row.orderId)
+          }
+        },
+      })
+    },
+    openForm(type, orderId) {
       this.$refs.tabPage.addTab({
       	// 对应显示的模块
       	activeKey: type,
       	// 唯一标识
       	key: type,
       	// 页签名称
-      	label: ({ remark: "备注" })[type],
+      	label: ({ add: '新增', edit: '编辑' })[type],
       	// 打开时事件
       	triggerEvent: () => {
       		this.formCancel()
       		this.$nextTick(()=>{
+            this.getGoodsSpecList();
+            this.getinitlbslist();
       			this.formType = type
       			this.formVisible = true
+            if (type == 'add') {
+      				this.formDialogType = 0
+      			} else if(type == 'edit'){
+      				this.formDialogType = 1
+      				getOfflineOrderDetail({ orderId }).then(res => {
+                this.goodsList = res.data.orderDetails;
+      				  Object.assign(this.formData, res.data)
+      				})
+      			}
       		})
       	},
       	// 关闭时事件
       	closeEvent: () => {
-			this.formCancel()
+			    this.formCancel()
       	}
       })
     },
@@ -157,16 +429,239 @@ export default {
     formConfirm(cancel) {
       this.$refs.formRef.validate((valid, invalidFields, errLabels) => {
         if (valid) {
-          ([saveRemark][this.formDialogType])(this.formData).then(res => {
+          offlineOrderSave({...this.formData, orderDetails: this.goodsList}).then(res => {
             this.$message({ type: 'success', message: `${this.formDialogTitles[this.formDialogType]}成功!` })
             cancel('list')
             this.$refs.pageRef.refreshList()
           })
         }
       })
-    }
+    },
+
+    openDetail(type, orderId) {
+      this.$refs.tabPage.addTab({
+      	// 对应显示的模块
+      	activeKey: type,
+      	// 唯一标识
+      	key: type,
+      	// 页签名称
+      	label: ({ detail: '详情', examine: '审核' })[type],
+      	// 打开时事件
+      	triggerEvent: () => {
+      		this.formCancel()
+      		this.$nextTick(()=>{
+            if (type == 'detail') {
+      				this.formDialogType = 0
+      			} else if(type == 'examine'){
+      				this.formDialogType = 1
+      			}
+            getOfflineOrderDetail({ orderId }).then(res => {
+              this.detailData = res.data;
+            })
+      		})
+      	},
+      	// 关闭时事件
+      	closeEvent: () => {
+			    this.detailCancel()
+      	}
+      })
+    },
+    detailCancel() {
+      this.formVisible = false
+      this.$refs?.formRef?.resetFields()
+      this.$data.formRef = this.$options.data().formRef
+    },
+    detailConfirm(cancel) {
+      this.$refs.formRef.validate((valid, invalidFields, errLabels) => {
+        if (valid) {
+          offlineOrderSave({...this.formData, orderDetails: this.goodsList}).then(res => {
+            this.$message({ type: 'success', message: `${this.formDialogTitles[this.formDialogType]}成功!` })
+            cancel('list')
+            this.$refs.pageRef.refreshList()
+          })
+        }
+      })
+    },
+
+    // 附件 - 上传成功
+    uploadSuccess(res, file) {
+      this.formData.fileUrl = res.data.url;
+    },
+
+    // 附件 - 上传前
+    beforeUpload(file) {
+      const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
+      const whiteList = ['jpg', 'jpeg', 'png'];
+      if (whiteList.indexOf(fileSuffix) === -1) {
+        this.$errorMsg('只支持上传jpg/png文件!');
+        return false;
+      }
+    },
+
+    getinitlbslist() {
+      // 初始化请求省市区街道下拉选项数据
+      lbsAmapRegion({ pid: 0 }).then(res => {
+        this.provinceList = res.data
+        // 创建工单时获取ip地址定位赋值
+        if (!this.id && this.$IpAdd.province) {
+          var item = this.provinceList.find(item => item.name === this.$IpAdd.province)
+          if (item) {
+            this.formData.provinceId = item.id
+            this.formData.province = item.name
+          }
+        }
+        if (this.formData.provinceId) {
+          lbsAmapRegion({ pid: this.formData.provinceId }).then(res => {
+            this.cityList = res.data
+            // 创建工单时获取ip地址定位赋值
+            if (!this.id && this.$IpAdd.city) {
+              var item2 = this.cityList.find(item => item.name === this.$IpAdd.city)
+              if (item2) {
+                this.formData.cityId = item2.id
+                this.formData.city = item2.name
+              }
+            }
+            if (this.formData.cityId) {
+              lbsAmapRegion({ pid: this.formData.cityId }).then(res => {
+                this.areaList = res.data
+              })
+            }
+            if (this.formData.areaId) {
+              lbsAmapRegion({ pid: this.formData.areaId }).then(res => {
+                this.streetList = res.data
+              })
+            }
+          })
+        }
+      })
+    },
+
+    selectAddress(data){
+      console.log(data);
+      this.formData.lng = data.center[0]
+      this.formData.lat = data.center[1]
+      // 获取定位的省市区街道
+      var { province, city, district, township } = data.data.addressComponent
+      // 获取选中省名称id
+      var { id, name } = this.provinceList.find(item => item.name === province)
+      this.formData.provinceId = id
+      this.formData.province = name
+      // 请求市选项
+      lbsAmapRegion({ pid: this.formData.provinceId }).then(res => {
+        // 赋值市选项
+        this.cityList = res.data
+        // 获取选中市名称id
+        var { id, name } = res.data.find(item => item.name === city)
+        this.formData.cityId = id
+        this.formData.city = name
+        // 请求区选项
+        lbsAmapRegion({ pid: this.formData.cityId }).then(res => {
+          // 赋值区选项
+          this.areaList = res.data
+          // 获取选中区名称id
+          var { id, name } = res.data.find(item => item.name === district)
+          this.formData.areaId = id
+          this.formData.area = name
+          // 请求街道选项
+          lbsAmapRegion({ pid: this.formData.areaId }).then(res => {
+            // 赋值街道选项
+            this.streetList = res.data
+            // 获取选中街道名称id
+            var { id, name } = res.data.find(item => item.name === township)
+            this.formData.streetId = id
+            this.formData.street = name
+            // 赋值GPS详细地址
+            this.formData.receAddress = data.name
+          })
+        })
+      })
+    },
+
+    // 获取规格列表
+    getGoodsSpecList() {
+      getGoodsSpecList({
+        pageNum: 1,
+        pageSize: -1,
+        specsName: '10'
+      }).then(res => {
+        this.goodsSpecList = res.data.records;
+      })
+    },
+
+    // 添加商品
+    addGoods() {
+      let obj = {
+        goodsMaterialId: '', // 物料编号
+        brandId: '', // 品牌id
+        brandName: '', // 品牌名称
+        mainId: '', // 大类id
+        mainName: '', // 大类名称
+        smallId: '', // 小类id
+        smallName: '', // 小类名称
+        goodsName: '', // 商品名称
+        specsName: '', // 规格名称
+        unit: '', // 单位
+        num: '', // 订单数量
+        insideQty: '', // 内机数量
+        outQty: '', // 外机数量
+        partsQty: '', // 配件数量
+        price: '', // 单价
+        amount: '', // 金额
+        stockQty: '', // 当前库存
+      }
+      let item = JSON.parse(JSON.stringify(obj));
+      this.goodsList.push(item);
+      console.log(this.goodsList);
+    },
+
+    // 删除规格
+    deleteGoods(index) {
+      this.goodsList.splice(index, 1);
+    },
+
+    // 选择规格型号
+    changeSpec(index, row) {
+      let item = this.goodsSpecList.find(o => o.id == row.goodsMaterialId);
+      this.goodsList[index].goodsMaterialId = item.id;
+      this.goodsList[index].mainId = item.mainId;
+      this.goodsList[index].mainName = item.mainName;
+      this.goodsList[index].smallId = item.smallId;
+      this.goodsList[index].smallName = item.smallName;
+      this.goodsList[index].goodsName = item.goodsName;
+      this.goodsList[index].specsName = item.specsName;
+      this.goodsList[index].unit = item.unit;
+      this.goodsList[index].stockQty = item.stockQty;
+    },
+
   }
 }
 </script>
 
 <style lang="scss" scoped></style>
+
+<style lang="scss">
+.specTable .el-table__cell {
+  padding: 0 !important;
+}
+
+// 图片墙
+.el-upload-list--picture-card .el-upload-list__item {
+  width: 100px;
+  height: 100px;
+}
+
+.el-upload--picture-card {
+  width: 100px;
+  height: 100px;
+  line-height: 100px;
+
+  .avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 100px;
+    height: 100px;
+    line-height: 100px;
+    text-align: center;
+  }
+}
+</style>