|
|
@@ -56,13 +56,13 @@
|
|
|
<form method="POST" action="{{url('customer/project/store')}}" class="mt-5">
|
|
|
@csrf
|
|
|
<div v-if="base == 'one'">
|
|
|
- @include("customer.project._one")
|
|
|
+ @include("customer.project.part._one")
|
|
|
</div>
|
|
|
<div v-if="base == 'two'">
|
|
|
- @include("customer.project._two")
|
|
|
+ @include("customer.project.part._two")
|
|
|
</div>
|
|
|
<div v-if="base == 'three'">
|
|
|
- @include("customer.project._three")
|
|
|
+ @include("customer.project.part._three")
|
|
|
</div>
|
|
|
<div class="row mt-3">
|
|
|
<div class="pull-right offset-7">
|
|
|
@@ -82,7 +82,7 @@
|
|
|
new Vue({
|
|
|
el:"#container",
|
|
|
data:{
|
|
|
- base:"one",
|
|
|
+ base:"three",
|
|
|
owner : {
|
|
|
id:"{{old('id') ?? ($owner->id ?? '') }}",
|
|
|
name : "{{old('name') ?? ($owner->name ?? '')}}",
|
|
|
@@ -161,6 +161,12 @@
|
|
|
{strategy:"特征"},
|
|
|
],
|
|
|
},
|
|
|
+ express:{
|
|
|
+ name:"",
|
|
|
+ initial_weight:"",
|
|
|
+ additional_weight:"",
|
|
|
+ items:[],
|
|
|
+ },
|
|
|
},
|
|
|
pool:{//基础数据选择池,以方便异步懒加载而非即时加载 例:units,owners等
|
|
|
counting_type:[
|
|
|
@@ -172,17 +178,24 @@
|
|
|
discount_type:[
|
|
|
"无减免","按单减免","固定减免"
|
|
|
],
|
|
|
+ feature_type:['商品名称','订单类型','承运商','店铺类型'],
|
|
|
+ logic : ['包含','不包含','等于'],
|
|
|
},
|
|
|
poolMapping:{//基础数据选择池的映射对象 供展示使用
|
|
|
|
|
|
},
|
|
|
selectedModel:{//已选定的计费模型
|
|
|
storage:[],
|
|
|
+ operation:[],
|
|
|
+ express:{},
|
|
|
},
|
|
|
thisOperationItemIndex:-1,//当前选中的作业费子项下标,用以唤起特征模态框
|
|
|
- oldFeature:"",//上一个特征,如果与当前特征一致则无需再次转换特征
|
|
|
+ operationItems:{},//控制作业费子项的渐入展开
|
|
|
+ importError:[],//导入时的错误数据原因
|
|
|
+ isShowError:false,//是否展开导入错误信息
|
|
|
},
|
|
|
mounted(){
|
|
|
+ $('[data-toggle="tooltip"]').tooltip();
|
|
|
if (this.errors.length===0 && this.owner.id){
|
|
|
this.display = true;
|
|
|
}
|
|
|
@@ -210,6 +223,9 @@
|
|
|
case "operation":
|
|
|
this._loadOperation();
|
|
|
break;
|
|
|
+ case "express":
|
|
|
+ this._loadExpress();
|
|
|
+ break;
|
|
|
}
|
|
|
this.type = type;
|
|
|
},
|
|
|
@@ -251,12 +267,6 @@
|
|
|
this.errors["owner_group_id"] = ["必须选择项目小组"];
|
|
|
this.$forceUpdate();
|
|
|
}
|
|
|
-/* this._requestRequest({
|
|
|
- customer_id:this.owner.customer_id,
|
|
|
- owner_group_id:this.owner.owner_group_id,
|
|
|
- tax_rate:this.owner.tax_rate,
|
|
|
- waring_line_on:this.owner.waring_line_on,
|
|
|
- },"three")*/
|
|
|
},
|
|
|
//上一步
|
|
|
back(){
|
|
|
@@ -290,6 +300,10 @@
|
|
|
_loadOperation(){
|
|
|
if (!this.pool.units)this._getUnits();
|
|
|
},
|
|
|
+ //加载快递
|
|
|
+ _loadExpress(){
|
|
|
+ if (!this.pool.provinces)this._getProvinces();
|
|
|
+ },
|
|
|
//获取单位
|
|
|
_getUnits(){
|
|
|
let url = "{{url('maintenance/unit/getUnits')}}";
|
|
|
@@ -303,12 +317,31 @@
|
|
|
this.$forceUpdate();
|
|
|
});
|
|
|
},
|
|
|
+ //获取省份
|
|
|
+ _getProvinces(){
|
|
|
+ let url = "{{url('maintenance/province/get')}}";
|
|
|
+ window.tempTip.postBasicRequest(url,{},res=>{
|
|
|
+ this.pool.provinces = res;
|
|
|
+ let mapping = [];
|
|
|
+ res.forEach(province=>{
|
|
|
+ mapping[province.id] = province.name;
|
|
|
+ });
|
|
|
+ this.poolMapping.provinces = mapping;
|
|
|
+ this.$forceUpdate();
|
|
|
+ });
|
|
|
+ },
|
|
|
//保存模型
|
|
|
saveModel(){
|
|
|
switch (this.type) {
|
|
|
case "storage":
|
|
|
this._verifyStorage();
|
|
|
break;
|
|
|
+ case "operation":
|
|
|
+ this._verifyOperation();
|
|
|
+ break;
|
|
|
+ case "express":
|
|
|
+ this._verifyExpress();
|
|
|
+ break;
|
|
|
}
|
|
|
},
|
|
|
_verifyStorage(){
|
|
|
@@ -344,6 +377,89 @@
|
|
|
};
|
|
|
this.errors = [];
|
|
|
},
|
|
|
+ _verifyOperation() {
|
|
|
+ if (this.selectedModel.operation.length>0){
|
|
|
+ this.selectedModel.operation.forEach(operation=>{
|
|
|
+ if (operation.operation_type === this.model.operation.operation_type && operation.strategy === this.model.operation.strategy){
|
|
|
+ this.errors["operation_type"] = ["已存在同类型的"+operation.operation_type+"作业计费模型"];
|
|
|
+ this.$forceUpdate();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!this.model.operation.name){
|
|
|
+ this.errors["name"] = ["名称不得为空"];
|
|
|
+ this.$forceUpdate();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if ((this.model.operation.operation_type === '出库' && this._verifyOperationItem(0)) || this._verifyOperationItem(1))return;
|
|
|
+ if (this.model.operation.items.length>2){
|
|
|
+ for (let i=2;i<this.model.operation.items.length;i++){
|
|
|
+ if (this._verifyOperationItem(i))return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (this.model.operation.operation_type === '入库')this.$delete(this.model.operation.items,0);//入库时干掉起步子项
|
|
|
+ this.selectedModel.operation.push(this.model.operation);
|
|
|
+ setTimeout(()=>{
|
|
|
+ this._renderingOperationItem(this.selectedModel.operation.length-1);
|
|
|
+ },100);
|
|
|
+ this.model.operation = {
|
|
|
+ operation_type:"入库",
|
|
|
+ strategy:"默认",
|
|
|
+ name:"",
|
|
|
+ feature:"",
|
|
|
+ items : [
|
|
|
+ {strategy:"起步"},
|
|
|
+ {strategy:"默认"},
|
|
|
+ {strategy:"特征"},
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ this.errors = [];
|
|
|
+ },
|
|
|
+ _verifyOperationItem(itemIndex){//验证作业费子项信息完整
|
|
|
+ let obj = this.model.operation.items[itemIndex];
|
|
|
+ let sign = false;
|
|
|
+ if (!obj.amount){
|
|
|
+ this.errors['items.'+itemIndex+'.amount'] = ["数量不得为空"];
|
|
|
+ sign = true;
|
|
|
+ }
|
|
|
+ if (!obj.unit_id){
|
|
|
+ this.errors['items.'+itemIndex+'.unit_id'] = ["必须选择单位"];
|
|
|
+ sign = true;
|
|
|
+ }
|
|
|
+ if (!obj.unit_price){
|
|
|
+ this.errors['items.'+itemIndex+'.unit_price'] = ["单价不得为空"];
|
|
|
+ }
|
|
|
+ if (sign)this.$forceUpdate();
|
|
|
+ return sign;
|
|
|
+ },
|
|
|
+ _verifyExpress(){
|
|
|
+ let error = {};
|
|
|
+ if (!this.model.express.name)error.name = ["名称不得为空"];
|
|
|
+ if (!this.model.express.initial_weight)error.initial_weight = ["首重不得为空"];
|
|
|
+ if (!this.model.express.additional_weight)error.additional_weight = ["续重不得为空"];
|
|
|
+ if (this.model.express.items.length>0){
|
|
|
+ this.model.express.items.forEach((item,index)=>{
|
|
|
+ if (!item.province_id)error["item."+index+".province_id"] = ["不存在"];
|
|
|
+ if (!item.initial_weight_price)error["item."+index+".initial_weight_price"] = ["不存在"];
|
|
|
+ if (!item.additional_weight_price)error["item."+index+".additional_weight_price"] = ["不存在"];
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (JSON.stringify(error) !== "{}"){
|
|
|
+ this.errors = error;
|
|
|
+ this.$forceUpdate();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.selectedModel.express = this.model.express;
|
|
|
+ this.model.express = {
|
|
|
+ name:"",
|
|
|
+ initial_weight:"",
|
|
|
+ additional_weight:"",
|
|
|
+ items:[],
|
|
|
+ };
|
|
|
+ this.errors = [];
|
|
|
+ this.importError = [];
|
|
|
+ },
|
|
|
//增加作业费特征子项
|
|
|
addOperationItem(){
|
|
|
this.model.operation.items.push({
|
|
|
@@ -355,45 +471,185 @@
|
|
|
this.$delete(this.model.operation.items,index);
|
|
|
},
|
|
|
//显示特征选择modal
|
|
|
- showAddFeatureModal(index,feature){
|
|
|
- if (!feature){
|
|
|
- this.model.operation.items[index].features = [{
|
|
|
- "strategyGroupStartSign": false,
|
|
|
- "calculation" : "",
|
|
|
- "type" : "",
|
|
|
- "id" : "",
|
|
|
- "logic" : "",
|
|
|
- "describe" : "",
|
|
|
- "strategyGroupEndSign" : false,
|
|
|
- }];
|
|
|
- this.thisOperationItemIndex = index;
|
|
|
- $("#addFeatureModal").modal("show");
|
|
|
- return;
|
|
|
- }
|
|
|
- if (this.oldFeature === feature) {
|
|
|
- this.thisOperationItemIndex = index;
|
|
|
- $("#addFeatureModal").modal("show");
|
|
|
- return;
|
|
|
+ showAddFeatureModal(index){
|
|
|
+ if (index === -1){
|
|
|
+ if (!this.model.operation.feature){
|
|
|
+ this.model.operation.features = this._createFeature();
|
|
|
+ this.thisOperationItemIndex = index;
|
|
|
+ this.$forceUpdate();
|
|
|
+ $("#addFeatureModal").modal("show");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.model.operation.features) {
|
|
|
+ this.thisOperationItemIndex = index;
|
|
|
+ $("#addFeatureModal").modal("show");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ if (!this.model.operation.items[index].feature){
|
|
|
+ this.model.operation.items[index].features = this._createFeature();
|
|
|
+ this.thisOperationItemIndex = index;
|
|
|
+ $("#addFeatureModal").modal("show");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.model.operation.items[index].features) {
|
|
|
+ this.thisOperationItemIndex = index;
|
|
|
+ $("#addFeatureModal").modal("show");
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
let url = "{{url('maintenance/priceModel/operation/getFeatures')}}";
|
|
|
+ let feature = index===-1 ? this.model.operation.feature : this.model.operation.items[index].feature;
|
|
|
window.tempTip.postBasicRequest(url,{feature:feature},res=>{
|
|
|
- this.features = res.data.data;
|
|
|
- this.oldFeature = feature;
|
|
|
- if (!this.features || this.features.length === 0){
|
|
|
- this.features = [{
|
|
|
- "strategyGroupStartSign": false,
|
|
|
- "calculation" : "",
|
|
|
- "type" : "",
|
|
|
- "id" : "", //特征ID
|
|
|
- "logic" : "", //特征逻辑
|
|
|
- "describe" : "", //特征信息
|
|
|
- "strategyGroupEndSign" : false,
|
|
|
- }];
|
|
|
+ if (!res.data.data || res.data.data.length === 0){
|
|
|
+ res.data.data = this._createFeature();
|
|
|
}
|
|
|
+ if (index === -1) this.model.operation.features = res.data.data;
|
|
|
+ else this.model.operation.items[index].features = res.data.data;
|
|
|
this.thisOperationItemIndex = index;
|
|
|
$("#addFeatureModal").modal("show");
|
|
|
});
|
|
|
},
|
|
|
+ //增加特征
|
|
|
+ addFeature(){
|
|
|
+ let obj = {
|
|
|
+ "strategyGroupStartSign": false,
|
|
|
+ "calculation" : "",
|
|
|
+ "type" : "",
|
|
|
+ "id" : "",
|
|
|
+ "logic" : "",
|
|
|
+ "describe" : "",
|
|
|
+ "strategyGroupEndSign" : false,
|
|
|
+ };
|
|
|
+ if (this.thisOperationItemIndex === -1)this.model.operation.features.push(obj);
|
|
|
+ else this.model.operation.items[this.thisOperationItemIndex].features.push(obj);
|
|
|
+ this.$forceUpdate();
|
|
|
+ },
|
|
|
+ _createFeature(){
|
|
|
+ return [{
|
|
|
+ "strategyGroupStartSign": false,
|
|
|
+ "calculation" : "",
|
|
|
+ "type" : "",
|
|
|
+ "id" : "",
|
|
|
+ "logic" : "",
|
|
|
+ "describe" : "",
|
|
|
+ "strategyGroupEndSign" : false,
|
|
|
+ }];
|
|
|
+ },
|
|
|
+ //删除特征
|
|
|
+ delFeature(index) {
|
|
|
+ if (this.thisOperationItemIndex === -1)this.$delete(this.model.operation.features,index);
|
|
|
+ else this.$delete(this.model.operation.items[this.thisOperationItemIndex].features,index);
|
|
|
+ this.$forceUpdate();
|
|
|
+ },
|
|
|
+ //提交特征更新现有
|
|
|
+ submitFeature(){
|
|
|
+ let url = "{{url('maintenance/priceModel/operation/getFeature')}}";
|
|
|
+ let features = this.thisOperationItemIndex === -1 ? this.model.operation.features : this.model.operation.items[this.thisOperationItemIndex].features;
|
|
|
+ window.tempTip.postBasicRequest(url,{features:features,isFormat:true},res=>{
|
|
|
+ if (this.thisOperationItemIndex === -1){
|
|
|
+ this.model.operation.feature = res.feature;
|
|
|
+ this.model.operation.featureFormat = res.featureFormat;
|
|
|
+ } else {
|
|
|
+ this.model.operation.items[this.thisOperationItemIndex].feature = res.feature;
|
|
|
+ this.model.operation.items[this.thisOperationItemIndex].featureFormat = res.featureFormat;
|
|
|
+ this.$forceUpdate();
|
|
|
+ }
|
|
|
+ $("#addFeatureModal").modal("hide");
|
|
|
+ return "已更新特征";
|
|
|
+ },true);
|
|
|
+ },
|
|
|
+ //渲染作业费子项
|
|
|
+ _renderingOperationItem(index){
|
|
|
+ let domId = "operation-"+index;
|
|
|
+ let trId = "operation-tr-"+index;
|
|
|
+ let itemId = "operation-item-"+index;
|
|
|
+ let html = "<tr class='d-none' id='"+trId+"'><td></td><td colspan='5'>"+
|
|
|
+ "<div id='"+itemId+"'><table class='table table-sm'>"+
|
|
|
+ "<th>子策略</th><th>数量</th><th>单位</th><th>单价</th><th>特征</th></th>";
|
|
|
+ this.selectedModel.operation[index].items.forEach(item=> {
|
|
|
+ html = this._createOperationItemList(html,item.strategy,item.amount,this.poolMapping.units[item.unit_id],item.unit_price,item.featureFormat ? item.featureFormat : '');
|
|
|
+ });
|
|
|
+ html += "</table></div></td></tr>";
|
|
|
+ $("#"+domId).after(html);
|
|
|
+ $("#"+itemId).slideUp();
|
|
|
+ },
|
|
|
+ _createOperationItemList(html,strategy,amount,unit,unit_price,feature){
|
|
|
+ html += "<tr><td>"+strategy+"</td><td>"+amount+"</td><td>"+unit+"</td><td>"+unit_price+"</td><td><div class='text-overflow-warp-100'>"+feature+"</div></td></tr>";
|
|
|
+ return html;
|
|
|
+ },
|
|
|
+ //移入移出时更改长文本显示效果
|
|
|
+ textClass(event,isOver){
|
|
|
+ event = event.target.children[0];
|
|
|
+ if (isOver) event.className = "text-overflow-warp-100";
|
|
|
+ else event.className = "cursor-pointer text-overflow-replace-100";
|
|
|
+ },
|
|
|
+ //展开子策略
|
|
|
+ showOperationItem(index){
|
|
|
+ let trId = "operation-tr-"+index;
|
|
|
+ let itemId = "operation-item-"+index;
|
|
|
+ if (this.operationItems['_'+index] && this.operationItems['_'+index]===true){
|
|
|
+ this.operationItems['_'+index] = false;
|
|
|
+ $("#"+itemId).slideUp(undefined,function () {
|
|
|
+ $("#"+trId).addClass("d-none");
|
|
|
+ });
|
|
|
+ }else {
|
|
|
+ $("#"+trId).removeClass("d-none");
|
|
|
+ this.operationItems['_'+index] = true;
|
|
|
+ $("#"+itemId).slideDown();
|
|
|
+ }
|
|
|
+ this.$forceUpdate();
|
|
|
+ },
|
|
|
+ //新增快递子项
|
|
|
+ addExpressItem(){
|
|
|
+ this.model.express.items.unshift({
|
|
|
+ province_id : "",
|
|
|
+ initial_weight_price:"",
|
|
|
+ additional_weight_price:"",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //删除快递子项
|
|
|
+ delExpressItem(index){
|
|
|
+ this.$delete(this.model.express.items,index);
|
|
|
+ },
|
|
|
+ //选择文件
|
|
|
+ selectFile(id){
|
|
|
+ this.importError = [];
|
|
|
+ $("#"+id).click();
|
|
|
+ },
|
|
|
+ //导入快递子项
|
|
|
+ importExpress(e){
|
|
|
+ let file=e.target.files[0];
|
|
|
+ if (!file){
|
|
|
+ tempTip.setDuration(3000);
|
|
|
+ tempTip.show("未选择文件");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let formData = new FormData();
|
|
|
+ formData.append("file",file);
|
|
|
+ axios.post('{{url('maintenance/priceModel/express/import')}}',formData,{
|
|
|
+ 'Content-Type':'multipart/form-data'
|
|
|
+ }).then(res=>{
|
|
|
+ if (res.data.success) {
|
|
|
+ res.data.data.forEach(data=>{
|
|
|
+ let unique = this.model.express.items.every(item=>{
|
|
|
+ if (data.province_id === item.province_id)return false;
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ if (unique)this.model.express.items.push(data);
|
|
|
+ });
|
|
|
+ this.importError = res.data.errors;
|
|
|
+ tempTip.setDuration(3000);
|
|
|
+ tempTip.showSuccess("导入成功!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ tempTip.setDuration(3000);
|
|
|
+ tempTip.show(res.data.data);
|
|
|
+ }).catch(err=> {
|
|
|
+ tempTip.setDuration(3000);
|
|
|
+ tempTip.show("网络错误:"+err);
|
|
|
+ })
|
|
|
+ }
|
|
|
},
|
|
|
});
|
|
|
</script>
|