Browse Source

编辑物料校验

yangc 7 years ago
parent
commit
73e4caa2d7

+ 10 - 0
src/main/webapp/resources/js/common/query/seekPurchase.js

@@ -100,6 +100,16 @@ define([ 'ngResource' ], function() {
             confirmBomSeekAll: {
                 url: 'seek/confirmBom',
                 method: 'POST'
+            },
+            // 删除bom物料
+            deleteBomProducts: {
+                url: 'seek/bom/detail/delete',
+                method: 'DELETE'
+            },
+            // 删除BOM
+            deleteBom: {
+                url: 'seek/bom/delete',
+                method: 'DELETE'
             }
 		});
 }])

+ 289 - 13
src/main/webapp/resources/js/usercenter/controllers/forstore/bomListDetailCtrl.js

@@ -3,7 +3,7 @@
  */
 define(['app/app'], function(app) {
     'use strict';
-    app.register.controller('bomListDetailCtrl', ['$scope', '$rootScope', 'ngTableParams', 'BaseService', 'toaster', 'Authority', '$stateParams', 'seekPurchase', function($scope, $rootScope, ngTableParams, BaseService, toaster, Authority, $stateParams, seekPurchase) {
+    app.register.controller('bomListDetailCtrl', ['$scope', '$rootScope', 'ngTableParams', 'BaseService', 'toaster', 'Authority', '$stateParams', 'seekPurchase', 'Search', function($scope, $rootScope, ngTableParams, BaseService, toaster, Authority, $stateParams, seekPurchase, Search) {
         document.title = '我的求购-优软商城';
         // 获取数据
         var loadData = function () {
@@ -12,13 +12,39 @@ define(['app/app'], function(app) {
                 if ($scope.bomData.seekPurchaseByBatchs) {
                     angular.forEach($scope.bomData.seekPurchaseByBatchs, function (item) {
                         item.$checked = false;
+                        item.showSimilarCodeList = false;
+                        item.showSimilarBrandList = false;
+                        item.isInCodeList = false;
+                        item.isInBrandList = false;
                     });
                 }
             }, function (err) {
-                toaster.pop('error', err);
+                toaster.pop('error', err.data);
             })
         }
         loadData();
+        // 获取字符长度
+        var getRealLen = function (str) {
+            var len = 0;
+            for (var i = 0; i < str.length; i++) {
+                if (str.charCodeAt(i) > 127 || str.charCodeAt(i) === 94) {
+                    len += 2;
+                } else {
+                    len++;
+                }
+            }
+            return len;
+        }
+        // 按字符数剪切字符串
+        var cutOutString = function (str, length) {
+            for (var i = 1; i <= str.length; i++) {
+                if (getRealLen(str.substr(0, i)) > length){
+                    str = str.substr(0, i-1);
+                    break;
+                }
+            }
+            return str;
+        };
         // 是否编辑BOM
         $scope.editBom = false;
         // 是否编辑询价
@@ -36,6 +62,9 @@ define(['app/app'], function(app) {
         $scope.endTimeOpen = {
             open: false
         };
+        // 发布询价截止日期限制
+        $scope.minDate = new Date();
+        $scope.maxDate = new Date(Date.now() + 1000 * 60 * 60 * 24 * 30 * 3);
         // 是否全选
         $scope.checkAll = false;
         // 初始化是否全选
@@ -62,11 +91,27 @@ define(['app/app'], function(app) {
             $scope.checkAll = flag;
             $scope.onCheckAllCheck();
         }
+        // 获取选中的物料数组
+        $scope.getCheckedProductIds = function () {
+            var checkedItems = []
+            angular.forEach($scope.bomData.seekPurchaseByBatchs, function (item) {
+                if (item.$checked) {
+                    checkedItems.push(item.id)
+                }
+            });
+            return checkedItems;
+        }
 
         // 取消/确认
         $scope.sure = function (flag) {
             if (flag) {
                 if ($scope.editBom) {
+                    // 批量验证
+                    for (var i = 0; i < $scope.bomData.seekPurchaseByBatchs.length; i++) {
+                        if ($scope.bomData.seekPurchaseByBatchs[i].$checked && !$scope.checkAllProduct($scope.bomData.seekPurchaseByBatchs[i])) {
+                            return;
+                        }
+                    }
                     // 保存BOM
                     seekPurchase.saveBomEdit({}, $scope.tmpEditBom, function (data) {
                         if (data.success) {
@@ -77,7 +122,7 @@ define(['app/app'], function(app) {
                             toaster.pop('error', data.message);
                         }
                     }, function (err) {
-                        toaster.pop(err);
+                        toaster.pop('error', err.data);
                     })
                 } else {
                     if (!$scope.seekObj.count) {
@@ -87,12 +132,7 @@ define(['app/app'], function(app) {
                     } else {
                         if (!$scope.checkAll) {
                             // 有无选中的
-                            var checkedItems = [];
-                            angular.forEach($scope.bomData.seekPurchaseByBatchs, function (item) {
-                                if (item.$checked) {
-                                    checkedItems.push(item.id)
-                                }
-                            });
+                            var checkedItems = $scope.getCheckedProductIds();
                             if (checkedItems.length == 0) {
                                 toaster.pop('error', '请选择发布的物料');
                             } else {
@@ -108,7 +148,7 @@ define(['app/app'], function(app) {
                                         toaster.pop('error', data.message);
                                     }
                                 }, function (err) {
-                                    toaster.pop('error', err);
+                                    toaster.pop('error', err.data);
                                 })
                             }
                         } else {
@@ -124,7 +164,7 @@ define(['app/app'], function(app) {
                                     toaster.pop('error', data.message);
                                 }
                             }, function (err) {
-                                toaster.pop('error', err);
+                                toaster.pop('error', err.data);
                             })
                         }
                     }
@@ -170,8 +210,9 @@ define(['app/app'], function(app) {
                 return;
             }
             if ($scope.editSeek) {
-                $scope.endTime = '';
-                $scope.count = '';
+                $scope.seekObj.endTime = '';
+                $scope.seekObj.count = '';
+                $scope.oldCount = 1;
             }
             if (!editSeek) {
                 $scope.setAllCheck(false);
@@ -184,11 +225,246 @@ define(['app/app'], function(app) {
             $event.stopPropagation();
             $scope.endTimeOpen.open = !$scope.endTimeOpen.open;
         };
+        // 设置截止日期
         $scope.changeEndTime = function () {
             if ($scope.seekObj.endTime) {
                 // 转换为23:59:59时间戳
                 $scope.seekObj.endTime = $scope.seekObj.endTime.getTime() + 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 59 * 1000;
             }
         }
+        // 采购数量临时变量
+        $scope.oldCount = 1;
+        // 采购数量输入校验
+        $scope.onCountChange = function () {
+            // 正整数且小于十万
+            if (!/^[1-9][0-9]*$/.test($scope.seekObj.count) || $scope.seekObj.count >= 100000) {
+                $scope.seekObj.count = $scope.oldCount;
+            } else {
+                $scope.oldCount = $scope.seekObj.count;
+            }
+        }
+        // 选中的物料id
+        $scope.selectedProductIds = [];
+        // 删除物料提示框
+        $scope.showDeleteBox = false;
+        // 删除物料提示
+        $scope.deleteProduct = function () {
+            if ($scope.editBom || $scope.editSeek) {
+                toaster.pop('info', '请先完成当前操作');
+                return;
+            }
+            $scope.selectedProductIds = $scope.getCheckedProductIds()
+            if ($scope. selectedProductIds.length > 0) {
+                $scope.showDeleteBox = true;
+            } else {
+                toaster.pop('info', '请选择需要删除的物料');
+            }
+        }
+        // 删除物料
+        $scope.doDeleteProduct = function () {
+            seekPurchase.deleteBomProducts({detailIds: $scope.selectedProductIds.join(',')}, null, function (data) {
+                if (data.success) {
+                    toaster.pop('success', '删除成功');
+                    loadData();
+                    $scope.showDeleteBox = false;
+                } else {
+                    toaster.pop('error', data.message);
+                }
+            }, function (err) {
+                toaster.pop('error', err.data);
+            })
+        }
+        // 删除BOM提示框
+        $scope.showDeleteBomBox = false;
+        $scope.deleteBom = function () {
+            $scope.showDeleteBomBox = true;
+        }
+        $scope.doDeleteBom = function () {
+            seekPurchase.deleteBom({bomId: $scope.bomData.id}, null, function (data) {
+                if (data.success) {
+                    toaster.pop('success', '删除成功');
+                    $scope.showDeleteBomBox = false;
+                    window.location.href = 'user#/seekPurchase?type=bomManage&bomTab=bomList';
+                } else {
+                    toaster.pop('error', data.message);
+                }
+            }, function (err) {
+                toaster.pop('error', err.data);
+            })
+        }
+        // bom字段校验(名字+规格)
+        $scope.onTmpEditBomChange = function (key) {
+            if (getRealLen($scope.tmpEditBom[key]) > 100) {
+                $scope.tmpEditBom.name = cutOutString($scope.tmpEditBom[key], 100);
+            }
+        }
+        // 校验特定的字符
+        $scope.checkNull = function (code) {
+            var str = code;
+            var filterStr = new Array("空", "没", "无", "-", "—", "null", "#N/A");
+            var flag = true;
+            angular.forEach (filterStr, function(item) {
+                if (str == item){
+                    flag = false;
+                    return;
+                }
+            })
+            return flag;
+        }
+        // 校验型号
+        $scope.checkCode = function (item) {
+            $scope.setShowSimilarList(item, 'showSimilarCodeList', item.isInCodeList);
+            var valid = item.code && item.code !== '';
+            if (!valid) {
+                toaster.pop('error', '型号不能为空');
+            }
+            if (!$scope.checkNull(item.code)){
+                toaster.pop('error', '型号输入不合法');
+                valid = false;
+            }
+            return valid;
+        }
+        // 校验品牌
+        $scope.checkBrand = function (item) {
+            $scope.setShowSimilarList(item, 'showSimilarBrandList', item.isInBrandList);
+            var vaild = item.brand
+                && item.brand !== '';
+            if (!vaild) {
+                toaster.pop('error', '品牌不能为空');
+            }
+            if (!$scope.checkNull(item.brand)){
+                toaster.pop('error', '品牌输入不合法');
+                vaild = false;
+            }
+            return vaild;
+        }
+        // 校验类目
+        $scope.checkKind = function (item) {
+            var valid = item.kind && item.kind !== '';
+            if (!valid) {
+                toaster.pop('error', '物料名称不能为空');
+            }
+            return valid;
+        }
+        // 校验规格
+        $scope.checkSpec = function (item) {
+            var valid;
+            if (!$scope.checkNull(item.spec)){
+                toaster.pop('error', '规格输入不合法');
+                valid = false;
+            } else {
+                valid = true;
+            }
+            return valid;
+
+        }
+        // 校验所有
+        $scope.checkAllProduct = function (item) {
+            return $scope.checkBrand(item) && $scope.checkKind(item) && $scope.checkCode(item) && $scope.checkSpec(item);
+        }
+        // 类目输入
+        $scope.onKindChange = function (item) {
+            if (item.kind && getRealLen(item.kind) > 40) {
+                item.kind = cutOutString(item.kind, 40);
+            }
+        };
+        // 规格输入
+        $scope.onSpecChange = function (item) {
+            if (item.spec && getRealLen(item.spec) > 100) {
+                item.spec = cutOutString(item.spec, 100);
+            }
+        };
+        // 型号输入
+        $scope.onCodeChange = function (item) {
+            if ((/[^\x00-\xff]/g).test(item.code)) {
+                var chineseIndex = -1;
+                for (var i = 0; i < item.code.length; i++) {
+                    if ((/[^\x00-\xff]/g).test(item.code.charAt(i))) {
+                        chineseIndex = i;
+                        break;
+                    }
+                }
+                item.code = cutOutString(item.code, chineseIndex);
+            } else if (item.code && getRealLen(item.code) > 100) {
+                item.code = cutOutString(item.code, 100);
+            } else {
+                if (item.code) {
+                    $scope.getSimilarCode(item);
+                } else {
+                    item.showSimilarCodeList = false;
+                }
+            }
+        }
+        // 品牌输入
+        $scope.onBrandChange = function (item) {
+            if ((/[^\x00-\xff]/g).test(item.brand)) {
+                var chineseIndex = -1;
+                for (var i = 0; i < item.brand.length; i++) {
+                    if ((/[^\x00-\xff]/g).test(item.brand.charAt(i)) && !(/[\u4e00-\u9fa5]/).test(item.brand.charAt(i))) {
+                        chineseIndex = i;
+                        break;
+                    }
+                }
+                if (chineseIndex > -1) {
+                    item.brand = item.brand.substring(0, chineseIndex);
+                }
+            } else if (item.brand && getRealLen(item.brand) > 50) {
+                item.brand = cutOutString(item.brand, 50);
+            } else {
+                if (item.brand) {
+                    $scope.getSimilarBrand(item);
+                } else {
+                    item.showSimilarBrandList = false;
+                }
+            }
+        }
+        // 单位用量输入
+        $scope.onAmountChange = function (item) {
+            if (!/^[1-9][0-9]*$/.test(item.amount)) {
+                item.amount = 1;
+            }
+            if (item.amount > 9999) {
+                item.amount = 9999;
+            } else if (item.amount < 1) {
+                item.amount = 1;
+            }
+        }
+
+        // 联想型号数据
+        $scope.similarCode = [];
+        // 联想品牌数据
+        $scope.similarBrand = [];
+        // 设置联想词的显示
+        $scope.setShowSimilarList = function (item, type, flag) {
+            item[type] = flag;
+        }
+        $scope.getSimilarCode = function (item) {
+            if (item.code) {
+                Search.getSimilarComponents({keyword : item.code}, function (data) {
+                    $scope.similarCode = data || [];
+                    $scope.setShowSimilarList(item, 'showSimilarCodeList', data && data.length);
+                }, function (error) {
+                    toaster.pop('error', '系统错误');
+                })
+            }
+        }
+        $scope.getSimilarBrand = function (item) {
+            if (item.brand) {
+                Search.getSimilarBrands({keyword : item.brand}, function (data) {
+                    $scope.similarBrand = data || [];
+                    $scope.setShowSimilarList(item, 'showSimilarBrandList', data && data.length);
+                }, function (error) {
+                    toaster.pop('error', '系统错误');
+                })
+            }
+        }
+        $scope.setCode = function (item, code) {
+            item.code = code;
+            $scope.setShowSimilarList(item, 'showSimilarCodeList', false);
+        }
+        $scope.setBrand = function (item, brand) {
+            item.brand = brand;
+            $scope.setShowSimilarList(item, 'showSimilarBrandList', false);
+        }
     }]);
 });

+ 104 - 14
src/main/webapp/resources/view/usercenter/forstore/bomListDetail.html

@@ -163,6 +163,36 @@
         width: 80px;
         text-align: right;
     }
+    .bom-list-detail .bom-list-table tbody tr td.base-info .content-line .similar-wrap {
+        position: relative;
+        overflow: unset;
+    }
+    .bom-list-detail .bom-list-table tbody tr td.base-info .content-line .similar-wrap ul.similar-list {
+        position: absolute;
+        top: 30px;
+        left: 0;
+        background: #fff;
+        border: 1px solid #b5b5b5;
+        z-index: 1;
+        max-height: 111px;
+        overflow-y: auto;
+        overflow-x: hidden;
+        border-radius: 3px;
+        width: 224px;
+        font-size: 12px;
+    }
+    .bom-list-detail .bom-list-table tbody tr td.base-info .content-line .similar-wrap ul.similar-list li {
+        height: 22px;
+        line-height: 22px;
+        cursor: pointer;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        padding: 0 5px;
+    }
+    .bom-list-detail .bom-list-table tbody tr td.base-info .content-line .similar-wrap ul.similar-list li:hover {
+        background: #ddd;
+    }
     .bom-list-detail .bom-list-table tbody tr td.base-info input {
         width: 100%;
         height: 30px;
@@ -179,8 +209,8 @@
         操作:
         <button class="operate-btn" ng-click="setEditSeek(true)">发布求购</button>
         <button class="operate-btn" ng-click="setEditBom(true)">编辑BOM</button>
-        <button class="operate-btn">删除物料</button>
-        <button class="operate-btn">删除本BOM</button>
+        <button class="operate-btn" ng-click="deleteProduct()">删除物料</button>
+        <button class="operate-btn" ng-click="deleteBom()">删除本BOM</button>
         <div class="fr" ng-show="editBom || editSeek">
             <button class="sure-btn" ng-click="sure(true)">确认</button>
             <button class="sure-btn cancel-btn" ng-click="sure(false)">取消</button>
@@ -191,18 +221,18 @@
             <li class="info-list-item">
                 <b>BOM名称:
                     <span ng-show="!editBom" ng-bind="bomData.name"></span>
-                    <input class="bom-input" ng-show="editBom" ng-model="tmpEditBom.name" type="text">
+                    <input class="bom-input" ng-show="editBom" ng-model="tmpEditBom.name" type="text" ng-change="onTmpEditBomChange('name')">
                 </b>
             </li>
             <li class="info-list-item"><b>本单共<span class="remind" ng-bind="bomData.amount || 0"></span>个产品</b></li>
             <li class="info-list-item">创建时间:{{bomData.releaseDate | date:'yyyy-MM-dd HH:mm:ss'}}</li>
             <li class="spec info-list-item">规格:
                 <span ng-show="!editBom" ng-bind="bomData.spec || '-'"></span>
-                <input class="bom-input" ng-show="editBom" ng-model="tmpEditBom.spec" type="text">
+                <input class="bom-input" ng-show="editBom" ng-model="tmpEditBom.spec" type="text" ng-change="onTmpEditBomChange('spec')">
             </li>
             <li class="expand amount info-list-item" ng-if="editSeek">
                 <i class="must">*</i>采购数量(套):
-                <input class="bom-input" type="text" ng-model="seekObj.count">
+                <input class="bom-input" type="text" ng-model="seekObj.count" ng-change="onCountChange()">
             </li>
             <li class="info-list-item expand date" ng-if="editSeek">
                 <i class="must">*</i>截止时间:
@@ -210,7 +240,8 @@
                        class="bom-input select-adder" placeholder="截止时间"
                        datepicker-popup="yyyy-MM-dd"
                        is-open="endTimeOpen.open"
-                       min-date="startDate" current-text="今天" clear-text="清除" close-text="关闭"
+                       min-date="minDate" max-date="maxDate"
+                       current-text="今天" clear-text="清除" close-text="关闭"
                        ng-click="openDatePicker($event)"
                        datepicker-options="{formatDayTitle: 'yyyy年M月', formatMonth: 'M月', showWeeks: false}"
                        ng-change="changeEndTime()"
@@ -246,9 +277,19 @@
                         <div class="inline-block title">
                             <i class="must">*</i>品牌:
                         </div>
-                        <div class="inline-block">
+                        <div class="inline-block similar-wrap">
                             <span ng-show="!editBom || !detail.$checked" ng-bind="detail.brand || '-'"></span>
-                            <input ng-show="editBom && detail.$checked"  ng-model="tmpEditBom.seekPurchaseByBatchs[$index].brand" type="text">
+                            <input ng-show="editBom && detail.$checked"
+                                   ng-model="detail.brand"
+                                   ng-change="onBrandChange(detail)"
+                                   ng-blur="checkBrand(detail)"
+                                   type="text">
+                            <ul class="similar-list"
+                                ng-show="detail.showSimilarBrandList"
+                                ng-mouseenter="detail.isInBrandList = true;"
+                                ng-mouseleave="detail.isInBrandList = false">
+                                <li ng-repeat="sBrand in similarBrand" ng-bind="sBrand.nameEn" title="{{sBrand.nameEn}}" ng-click="setBrand(detail, sBrand.nameEn)"></li>
+                            </ul>
                         </div>
                     </div>
                     <div class="content-line">
@@ -257,7 +298,11 @@
                         </div>
                         <div class="inline-block">
                             <span ng-show="!editBom || !detail.$checked" ng-bind="detail.kind || '-'"></span>
-                            <input ng-show="editBom && detail.$checked" ng-model="tmpEditBom.seekPurchaseByBatchs[$index].kind" type="text">
+                            <input ng-show="editBom && detail.$checked"
+                                   ng-model="detail.kind"
+                                   ng-change="onKindChange(detail)"
+                                   ng-blur="checkKind(detail)"
+                                   type="text">
                         </div>
                     </div>
                 </td>
@@ -266,18 +311,32 @@
                         <div class="inline-block title">
                             <i class="must">*</i>型号:
                         </div>
-                        <div class="inline-block">
+                        <div class="inline-block similar-wrap">
                             <span ng-show="!editBom || !detail.$checked" ng-bind="detail.code || '-'"></span>
-                            <input ng-show="editBom && detail.$checked" ng-model="tmpEditBom.seekPurchaseByBatchs[$index].code" type="text">
+                            <input ng-show="editBom && detail.$checked"
+                                   ng-model="detail.code"
+                                   ng-change="onCodeChange(detail)"
+                                   ng-blur="checkCode(detail)"
+                                   type="text">
+                            <ul class="similar-list"
+                                ng-show="detail.showSimilarCodeList"
+                                ng-mouseenter="detail.isInCodeList = true;"
+                                ng-mouseleave="detail.isInCodeList = false">
+                                <li ng-repeat="sCode in similarCode" ng-bind="sCode.code" title="{{sCode.code}}" ng-click="setCode(detail, sCode.code)"></li>
+                            </ul>
                         </div>
                     </div>
                     <div class="content-line">
                         <div class="inline-block title">
-                            <i class="must">*</i>规格:
+                            规格:
                         </div>
                         <div class="inline-block">
                             <span ng-show="!editBom || !detail.$checked" ng-bind="detail.spec || '-'"></span>
-                            <input ng-show="editBom && detail.$checked" ng-model="tmpEditBom.seekPurchaseByBatchs[$index].spec" type="text">
+                            <input ng-show="editBom && detail.$checked"
+                                   ng-model="detail.spec"
+                                   ng-change="onSpecChange(detail)"
+                                   ng-blur="checkSpec(detail)"
+                                   type="text">
                         </div>
                     </div>
                 </td>
@@ -288,11 +347,42 @@
                         </div>
                         <div class="inline-block">
                             <span ng-show="!editBom || !detail.$checked" ng-bind="detail.amount || '-'"></span>
-                            <input ng-show="editBom && detail.$checked" ng-model="tmpEditBom.seekPurchaseByBatchs[$index].amount" type="text">
+                            <input ng-show="editBom && detail.$checked"
+                                   ng-model="detail.amount"
+                                   ng-change="onAmountChange(detail)"
+                                   type="text">
                         </div>
                     </div>
                 </td>
             </tr>
         </tbody>
     </table>
+    <div class="com-modal-wrap" ng-if="showDeleteBox">
+        <div class="com-mall-del-box">
+            <div class="title">
+                <i ng-click="showDeleteBox = false"></i>
+            </div>
+            <div class="content">
+                <p><i class="fa fa-exclamation-circle"></i>删除选中的{{selectedProductIds.length}}个物料?</p>
+                <div>
+                    <a ng-click="showDeleteBox = false">取消</a>
+                    <a ng-click="doDeleteProduct()">确认</a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="com-modal-wrap" ng-if="showDeleteBomBox">
+        <div class="com-mall-del-box">
+            <div class="title">
+                <i ng-click="showDeleteBomBox = false"></i>
+            </div>
+            <div class="content">
+                <p><i class="fa fa-exclamation-circle"></i>是否删除当前BOM?</p>
+                <div>
+                    <a ng-click="showDeleteBomBox = false">取消</a>
+                    <a ng-click="doDeleteBom()">确认</a>
+                </div>
+            </div>
+        </div>
+    </div>
 </div>