操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    (2018年8月21日,/HRoot.com/)最新的Monster印度就業指數顯示,2018年7月印度在線招聘活動指數同比下滑2%。

    該指數是知名在線招聘網站Monster.com衡量每月在線招聘活動的指標,記錄了招聘活動增長最高和最低的行業與職業。

    Monster就業指數顯示,繼2018年6月和5月印度在線招聘活動指數分別下滑8%和7%之后,7月月度就業指數反彈了6%。

    在被分析的所有行業中,7月份生產和制造業的長期同比增幅連續第四個月最高,達到了60%。在過去6個月中,該行業的招聘需求增長了28%。

    與2017年相比,零售業在2018年7月的在線招聘活動增加了41%。

    Monster.com亞太和海灣地區首席執行官Abhijeet Mukherjee表示:“盡管自2018年6月以來印度制造業的表現已經有所放緩,但根據Monster就業指數分析,生產和制造業在線招聘已經連續第四個月上升。”

    “這可能是國內和出口增長訂單持續推動的結果,促使企業提高了員工數量。此外,零售業也出現了驚人的增長,這可能是由于季末銷售和折扣導致的網上購物激增。”Mukherjee說。

    從不同工作崗位類別來看,財務與會計(增長24%)和人力資源管理(增長24%)的需求同比增長最為顯著。

    就城市數據而言,昌迪加爾7月份在線招聘指數增長了18%,齋浦爾(增長12%)和哥印拜陀(增長10%)緊隨其后。

    INDIA – ONLINE RECRUITMENT SLIPS 2% IN JULY, ACCORDING TO MONSTER EMPLOYMENT INDEX

    (Aug.21, 2018, /staffingindustry.com/)The Monster Employment Index for India showed online recruitment fell by 2% in July 2018 compared to the previous year.

    The index is a monthly gauge of online job hiring activity by Monster.com, which records the industries and occupations that show the highest and lowest growth.

    Monster’s employment index added that monthly hiring rebounded 6%, following a decline of 8% in June and 7% in May 2018.

    For the fourth consecutive month, the Production and Manufacturing sector saw the highest long-term year-on-year growth at 60% in July among the other sectors analysed. The sector has seen 28% growth in hiring demand in the past six months between January and July 2018.

    The Retail sector recorded a 41% increase in online recruitment activity in July 2018, when compared to last year.

    Abhijeet Mukherjee, CEO, Monster.com, APAC & Gulf commented, “Although the performance of the manufacturing sector in India itself has softened since June 2018, the online hiring in the production & manufacturing sector analysed by MEI has seen an upswing for the fourth consecutive month.”

    “This could be result of the sustained impetus in domestic and export growth orders have encouraged firms to raise their staffing levels. Moreover, the Retail sector has also shown a phenomenal growth surge which can be attributed to a spurt in online shopping owing to end of season sale and discounts,” Mukherjee said.

    Among job roles, Finance & Accounting (up 24%) and HR & Admin (up 24%) registered the most notable increase in demand on a year-on-year basis.

    In terms of data by city, Chandigarh reported that online recruitment grew 18% in July, followed by Jaipur (up 12%) and Coimbatore (up 10%).

    微信:人力資源市場觀察

    博主給大家推薦一套全部開源的H5電商項目「waynboot-mall」。由博主在2020年開發至今,已有三年之久。那時候網上很多的H5商城項目都是半開源版本,要么沒有H5前端代碼,要么需要加群咨詢,屬實惡心。于是博主決定自己開發一套完整的移動端H5商城,包含一個管理后臺、一個前臺H5商城、一套后端接口。項目地址如下:

    • H5商城前端代碼:https://github.com/wayn111/waynboot-mobile
    • 運營后臺前端代碼:https://github.com/wayn111/waynboot-admin
    • 后端接口代碼:https://github.com/wayn111/waynboot-mall

    歡迎大家關注這個項目,點個Star讓更多的人了解到這個項目。

    一、簡介

    「waynboot-mall」是一套全部開源的微商城項目,實現了一個商城所需的首頁展示、商品分類、商品詳情、sku組合、商品搜索、購物車、結算下單、訂單狀態流轉、商品評論等一系列功能。 技術上基于最新得Spring Boot3.0、Jdk17,整合了Redis、RabbitMQ、ElasticSearch等常用中間件, 貼近生產環境實際經驗開發而來。


    二、技術特點

    1. 訂單金額計算使用BigDeciaml類型,支持小數點后兩位
    2. 支持微信內JsApi支付、H5網頁支付
    3. 商城接口代碼清晰、注釋完善、模塊拆分合理
    4. 使用Spring-Security進行訪問權限控制
    5. 使用jwt進行接口授權驗證
    6. ORM層使用Mybatis Plus提升開發效率
    7. 添加全局異常處理器,統一異常處理
    8. 使用Spring Boot admin進行服務監控
    9. 集成七牛云存儲配置,支持上傳文件至七牛獲取cdn下載鏈接
    10. 集成常用郵箱配置,方便發送郵件
    11. 添加策略模式使用示例,優化首頁金剛區跳轉邏輯
    12. 拆分出通用的數據訪問模塊,統一Redis & Elastic配置與訪問
    13. 使用Elasticsearch高級客戶端依賴對Elasticsearch進行操作
    14. 支持商品數據同步Elasticsearch操作以及中文分詞搜索
    15. RabbitMQ生產者發送消息采用異步confirm模式,消費者消費消息時需手動確認確保消息不丟失
    16. 下單處理過程引入RabbitMQ,異步生成訂單記錄,提高系統下單處理能力

    三、商城設計

    文項目目錄

    |-- waynboot-monitor               // 監控模塊
    |-- waynboot-admin-api             // 運營后臺api模塊,提供后臺項目api接口
    |-- waynboot-common                // 通用模塊,包含項目核心基礎類
    |-- waynboot-data                  // 數據模塊,通用中間件數據訪問
    |   |-- waynboot-data-redis        // redis訪問配置模塊
    |   |-- waynboot-data-elastic      // elastic訪問配置模塊
    |-- waynboot-generator             // 代碼生成模塊
    |-- waynboot-message-consumer      // 消費者模塊,處理訂單消息和郵件消息
    |-- waynboot-message-core          // 消費者核心模塊,隊列、交換機配置
    |-- waynboot-mobile-api            // h5商城api模塊,提供h5商城api接口
    |-- pom.xml                        // maven父項目依賴,定義子項目依賴版本
    |-- ...
    

    技術亮點

    2.1 庫存扣減

    庫存扣減操作是在下單操作扣減還是在支付成功時扣減?(ps:扣減庫存使用樂觀鎖機制 where goods_num - num >=0

    1. 下單時扣減,這個方案屬于實時扣減,當有大量下單請求時,由于訂單數小于請求數,會發生下單失敗,但是無法防止短時間大量惡意請求占用庫存, 造成普通用戶無法下單
    2. 支付成功扣減,這個方案可以預防惡意請求占用庫存,但是會存在多個請求同時下單后,在支付回調中扣減庫存失敗,導致訂單還是下單失敗并且還要退還訂單金額(這種請求就是訂單數超過了庫存數,無法發貨,影響用戶體驗)
    3. 還是下單時扣減,但是對于未支付訂單設置一個超時過期機制,比如下單時庫存減一,生成訂單后,對于未在15分鐘內完成支付的訂單, 自動取消超期未支付訂單并將庫存加一,該方案基本滿足了大部分使用場景
    4. 針對大流量下單場景,比如一分鐘內五十萬次下單請求,可以通過設置虛擬庫存的方式減少下單接口對數據庫的訪問。具體來說就是把商品庫存緩存到redis中, 下單時配合lua腳本原子的get和decr商品庫存數量(這一步就攔截了大部分請求),執行成功后在扣減實際庫存

    2.2 首頁查詢

    首頁商品展示接口利用多線程技術進行查詢優化,將多個sql語句的排隊查詢變成異步查詢,接口時長只跟查詢時長最大的sql查詢掛鉤

    // 使用CompletableFuture異步查詢
    List<CompletableFuture<Void>> list=new ArrayList<>();
    CompletableFuture<Void> f1=CompletableFuture.supplyAsync(() -> iBannerService.list(Wrappers.lambdaQuery(Banner.class).eq(Banner::getStatus, 0).orderByAsc(Banner::getSort)), homeThreadPoolTaskExecutor).thenAccept(data -> {
        String key="bannerList";
        redisCache.setCacheMapValue(SHOP_HOME_INDEX_HASH, key, data);
        success.add(key, data);
    });
    CompletableFuture<Void> f2=CompletableFuture.supplyAsync(() -> iDiamondService.list(Wrappers.lambdaQuery(Diamond.class).orderByAsc(Diamond::getSort).last("limit 10")), homeThreadPoolTaskExecutor).thenAccept(data -> {
        String key="categoryList";
        redisCache.setCacheMapValue(SHOP_HOME_INDEX_HASH, key, data);
        success.add(key, data);
    });
    list.add(f1);
    list.add(f2);
    // 主線程等待子線程執行完畢
    CompletableFuture.allOf(list.toArray(new CompletableFuture[0])).join();
    

    2.3 中文分詞搜索

    ElasticSearch搜索查詢,查詢包含搜索關鍵字并且是上架中的商品,在根據指定字段進行排序,最后分頁返回

    SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
    BoolQueryBuilder boolQueryBuilder=QueryBuilders.boolQuery();
    MatchQueryBuilder matchFiler=QueryBuilders.matchQuery("isOnSale", true);
    MatchQueryBuilder matchQuery=QueryBuilders.matchQuery("name", keyword);
    MatchPhraseQueryBuilder matchPhraseQueryBuilder=QueryBuilders.matchPhraseQuery("keyword", keyword);
    boolQueryBuilder.filter(matchFiler).should(matchQuery).should(matchPhraseQueryBuilder).minimumShouldMatch(1);
    searchSourceBuilder.timeout(new TimeValue(10, TimeUnit.SECONDS));
    // 按是否新品排序
    if (isNew) { 
        searchSourceBuilder.sort(new FieldSortBuilder("isNew").order(SortOrder.DESC));
    }
    // 按是否熱品排序
    if (isHot) {
        searchSourceBuilder.sort(new FieldSortBuilder("isHot").order(SortOrder.DESC));
    }
    // 按價格高低排序
    if (isPrice) {
        searchSourceBuilder.sort(new FieldSortBuilder("retailPrice").order("asc".equals(orderBy) ? SortOrder.ASC : SortOrder.DESC));
    }
    // 按銷量排序
    if (isSales) {
        searchSourceBuilder.sort(new FieldSortBuilder("sales").order(SortOrder.DESC));
    }
    // 篩選新品
    if (filterNew) {
        MatchQueryBuilder filterQuery=QueryBuilders.matchQuery("isNew", true);
        boolQueryBuilder.filter(filterQuery);
    }
    // 篩選熱品
    if (filterHot) {
        MatchQueryBuilder filterQuery=QueryBuilders.matchQuery("isHot", true);
        boolQueryBuilder.filter(filterQuery);
    }
    
    searchSourceBuilder.query(boolQueryBuilder);
    searchSourceBuilder.from((int) (page.getCurrent() - 1) * (int) page.getSize());
    searchSourceBuilder.size((int) page.getSize());
    List<JSONObject> list=elasticDocument.search("goods", searchSourceBuilder, JSONObject.class);
    

    2.4 訂單編號

    訂單編號生成規則:秒級時間戳 + 加密用戶ID + 今日第幾次下單

    1. 秒級時間戳:時間遞增保證唯一性
    2. 加密用戶ID:加密處理,返回用戶ID6位數字,可以防并發訪問,同一秒用戶不會產生2個訂單
    3. 今日第幾次下單:便于運營查詢處理用戶當日訂單
    /**
     * 返回訂單編號,生成規則:秒級時間戳 + 加密用戶ID + 今日第幾次下單
     *
     * @param userId 用戶ID
     * @return 訂單編號
     */
    public static String generateOrderSn(Long userId) {
            long now=LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
            return now + encryptUserId(String.valueOf(userId), 6) + countByOrderSn(userId);
    }
    
    /**
     * 計算該用戶今日內第幾次下單
     *
     * @param userId 用戶ID
     * @return 該用戶今日第幾次下單
     */
    public static int countByOrderSn(Long userId) {
            IOrderService orderService=SpringContextUtil.getBean(IOrderService.class);
            return orderService.count(new QueryWrapper<Order>().eq("user_id", userId)
            .gt("create_time", LocalDate.now())
            .lt("create_time", LocalDate.now().plusDays(1)));
    }
    
    /**
     * 加密用戶ID,返回num位字符串
     *
     * @param userId 用戶ID
     * @param num    長度
     * @return num位加密字符串
     */
    private static String encryptUserId(String userId, int num) {
            return String.format("%0" + num + "d", Integer.parseInt(userId) + 1);
    }
    

    2.5 異步下單

    下單流程處理過程,通過rabbitMQ異步生成訂單,提高系統下單處理能力

    1. 用戶點擊提交訂單按鈕,后臺生成訂單編號和訂單金額跳轉到訂單支付頁面,并將訂單編號等信息發送rabbitMQ消息(生成訂單編號,還未生成訂單)
    2. 訂單消費者接受到訂單消息后,獲取訂單編號生成訂單記錄(訂單創建成功,用戶待支付)
    3. 下單頁面,前端根據訂單編號輪詢訂單接口,訂單已創建則跳轉支付頁面,否則提示下單失敗(訂單創建失敗)
    4. 支付頁面,用戶點擊支付按鈕時,后臺調用微信/支付寶下單接口后,前端喚醒微信/支付寶支付,用戶輸入密碼
    5. 用戶支付完成后在微信/支付寶下回調通知里更新訂單狀態為已支付(訂單已支付)
    6. 用戶支付完成后,返回支付狀態查看頁面。

    2.6 設計模式

    金剛區跳轉使用策略模式進行代碼編寫

    1.定義金剛位跳轉策略接口以及跳轉枚舉類

    public interface DiamondJumpType {
    
        List<Goods> getGoods(Page<Goods> page, Diamond diamond);
    
        Integer getType();
    }
    
    // 金剛位跳轉類型枚舉
    public enum JumpTypeEnum {
        COLUMN(0),
        CATEGORY(1);
    
        private Integer type;
    
        JumpTypeEnum(Integer type) {
            this.type=type;
        }
    
        public Integer getType() {
            return type;
        }
    
        public JumpTypeEnum setType(Integer type) {
            this.type=type;
            return this;
        }
    }
    

    2.定義策略實現類,并使用@Component注解注入spring

    // 分類策略實現
    @Component
    public class CategoryStrategy implements DiamondJumpType {
    
        @Autowired
        private GoodsMapper goodsMapper;
    
        @Override
        public List<Goods> getGoods(Page<Goods> page, Diamond diamond) {
            List<Long> cateList=Arrays.asList(diamond.getValueId());
            return goodsMapper.selectGoodsListPageByl2CateId(page, cateList).getRecords();
        }
    
        @Override
        public Integer getType() {
            return JumpTypeEnum.CATEGORY.getType();
        }
    }
    
    // 欄目策略實現
    @Component
    public class ColumnStrategy implements DiamondJumpType {
    
        @Autowired
        private IColumnGoodsRelationService iColumnGoodsRelationService;
    
        @Autowired
        private IGoodsService iGoodsService;
    
        @Override
        public List<Goods> getGoods(Page<Goods> page, Diamond diamond) {
            List<ColumnGoodsRelation> goodsRelationList=iColumnGoodsRelationService.list(new QueryWrapper<ColumnGoodsRelation>()
                    .eq("column_id", diamond.getValueId()));
            List<Long> goodsIdList=goodsRelationList.stream().map(ColumnGoodsRelation::getGoodsId).collect(Collectors.toList());
            Page<Goods> goodsPage=iGoodsService.page(page, new QueryWrapper<Goods>().in("id", goodsIdList).eq("is_on_sale", true));
            return goodsPage.getRecords();
        }
    
        @Override
        public Integer getType() {
            return JumpTypeEnum.COLUMN.getType();
        }
    }
    

    3.定義策略上下文,通過構造器注入spring,定義map屬性,通過key獲取對應策略實現類

    @Component
    public class DiamondJumpContext {
    
        private final Map<Integer, DiamondJumpType> map=new HashMap<>();
    
        /**
         * 由spring自動注入DiamondJumpType子類
         *
         * @param diamondJumpTypes 金剛位跳轉類型集合
         */
        public DiamondJumpContext(List<DiamondJumpType> diamondJumpTypes) {
            for (DiamondJumpType diamondJumpType : diamondJumpTypes) {
                map.put(diamondJumpType.getType(), diamondJumpType);
            }
        }
    
        public DiamondJumpType getInstance(Integer jumpType) {
            return map.get(jumpType);
        }
    }
    

    4.使用,注入DiamondJumpContext對象,調用getInstance方法傳入枚舉類型

    @Autowired
    private DiamondJumpContext diamondJumpContext;
    
    @Test
    public void test(){
        DiamondJumpType diamondJumpType=diamondJumpContext.getInstance(JumpTypeEnum.COLUMN.getType());
    }
    

    四、演示圖

    商城登陸

    商城注冊

    商城首頁

    商城搜索

    搜索結果展示

    金剛位跳轉

    商品分類

    商品詳情

    商品sku選擇

    購物車查看

    確認下單

    選擇支付方式

    商城我的頁面

    我的訂單列表

    添加商品評論

    查看商品評論

    后臺登陸

    后臺首頁

    后臺會員管理

    后臺評論管理

    后臺地址管理

    后臺添加商品

    后臺商品管理

    后臺banner管理

    后臺訂單管理

    后臺分類管理

    后臺金剛區管理

    后臺欄目管理


    五、在線體驗

    演示地址:http://121.4.124.33/mall

    最后說兩句「waynboot-mall」作為博主的開源項目集大成者,對于沒有接觸過商城項目的小伙伴來說是非常具有幫助和學習價值的。看完這個項目你能了解到一個商城項目的基本全貌,提前避坑。

    感謝大家閱讀,希望這篇文章能為你提供價值。博主每周分享技術干貨、開源項目、實戰經驗、高效開發工具等,您的關注將是我的更新動力。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有