معرفی پروژه فروشگاهی Iris Store
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: پنج دقیقه

پروژه IrisStore، یک سیستم فروشگاهی متن باز برای راه اندازی فروشگاه‌های اینترنتی کوچک است که سورس آن را می‌توانید از آدرس زیر دریافت کنید و برای اجرای آن نیاز به VS 2015 دارید (به دلیل استفاده‌ی از قابلیت‌های جدید زبان سی‌شارپ):
 
https://github.com/MehdiSaeedifar/IrisStore
 
همچنین نمونه‌ی آنلاین آن‌را می‌توانید در فروشگاه آیریس مشاهده کنید.
 

در ادامه برخی از قابلیت‌های این سیستم را مشاهده می‌کنید:
 

جست و جو با قابلیت دسته بندی نتایج

 
به هنگام جست و جو، لیستی از موارد پیشنهادی به صورت دسته بندی شده نمایش داده می‌شود.



جست و جوی پیشرفته کالا‌ها
 
جست و جو بر اساس قیمت، گروه، کلمات کلیدی و مرتب سازی نتایج انجام می‌گیرد. همچنین نتایج جست و جو بدون رفرش شدن صفحه و به صورت AJAX ای به همراه تغییر URL صفحه صورت می‌گیرد.



نمایش نمودار تغییرات قیمت
 
امکان نمایش نمودار تغییرات قیمت کالا در بازه‌ی زمانی نیز پیش بینی شده است.

   
ویرایش اطلاعات به صورت inline
 
امکان ویرایش قیمت و تاریخ به صورت inline وجود دارد.



   

مدیریت تصاویر کالا

 
در این قسمت امکان آپلود همزمان چندین فایل به همراه پیش نمایش آن‌ها وجود دارد. همچنین امکان کشیدن و رها کردن برای تغییر ترتیب چیدمان عکس‌ها نیز مهیا است.( تصویر اول به عنوان کاور کالا در نظر گرفته می‌شود.)


   

قابلیت‌های دیگر:

 
- مدیریت تصاویر اسلایدشو و تغییر ترتیب آن‌ها از طریق کشیدن و رها کردن (drag & drop)
- تعریف برگه و تغییر ترتیب نمایش آن‌ها از طریق کشیدن و رها کردن
- امکان ارسال پست
- تعریف دسته بندی
- مدیریت کاربران
- تعریف تنظیمات سایت
- نمایش کالا و پست‌های مشابه

کارهایی که باید انجام شود:

 
- پیاده سازی سبد خرید و خرید آنلاین
 

تصویر پنل مدیریت

 

تصویر صفحه‌ی اصلی:



همچنین به راحتی می‌توان با طراحی قالب جدیدی، از این سیستم برای کاری غیر از فروشگاه اینترنتی استفاده کرد؛ سایت‌های زیر نمونه‌های آنلاین دیگری از این سیستم هستند:

- http://www.petrapars.ir
- http://www.ava-tarh.ir
  
در نهایت فهرستی از کتاب خانه‌ها و فناوری‌های استفاده شده و همچنین مقالات مرتبط با این پروژه را قرار داده‌ام.

کتابخانه‌ها و فریم ورک‌های سمت سرور:

 فناوری یا کتابخانه   توضیحات  
مقالات مرتبط
 ASP.NET MVC 5.x
 فریم ورک و موتور اصلی سایت
-ASP.NET MVC
-How to handle repeating form fields in ASP MVC
-How to dynamically (via AJAX) add new items to a bound list model, in ASP MVC.NET  
 Entity Framework 6.x
 فریم ورک دسترسی به داده
-Entity framework code-first
-Update One-to-Many Entity using DBContext 
-مدیریت اطلاعات وابسته به زمان در بانک‌های اطلاعاتی رابطه‌ای
EFSecondLevelCache
کش سطح دوم EF 6
 -بازنویسی سطح دوم کش برای Entity framework 6  
 AutoMapper
 نگاشت اطلاعات یک شی به شی دیگر به صورت خودکار  - دوره AutoMapper
- خودکارسازی فرآیند نگاشت اشیاء در AutoMapper  
 StructureMap
 تزریق وابستگی‌ها
-EF Code First #12  
 MvcCheckBoxList
 اضافه کردن CheckBoxList  به HtmlHelper 

 DNTScheduler
 برای انجام کارهای زمان بندی شده
-انجام کارهای زمانبندی شده در برنامه‌های ASP.NET توسط DNT Scheduler
 Lucene.Net
 موتور جستجوی سایت  -جستجوی سریع و پیشرفته با لوسین Lucene.net  
 AspNet.Identity
 سیستم مدیریت کاربران
-اعمال تزریق وابستگی‌ها به مثال رسمی ASP.NET Identity  
 ELMAH.MVC
 کتابخانه ثبت وقایع و خطا‌های سیستم  -معرفی ELMAH
 PagedList
 نمایش اطلاعات به صورت صفحه بندی شده

PersianDateTime
جایگزینی است برای System.DateTime برای تاریخ‌های شمسی
-PersianDateTime جایگزینی برای System.DateTime
T4MVC
تعاریف Strongly typed مسیرها 
-T4MVC : یکی از الزامات مدیریت پروژه‌های ASP.NET MVC
Dynamic LINQ
نوشتن کوئری‌های LINQ به صورت رشته ای
-انتخاب پویای فیلد‌ها در LINQ
-فعال سازی و پردازش جستجوی پویای jqGrid در ASP.NET MVC 

کتابخانه‌های جاوا اسکریپتی سمت کلاینت:
 
 فناوری یا کتابخانه  
  توضیحات     مقالات مرتبط 
 jQuery  کتاب خانه‌ی پایه جاوا اسکرپتی سایت
 -آموزش (jQuery) جی کوئری
-آموزش JQuery Plugin و مباحث پیشرفته جی کوئری  
 
 jQuery UI  ویجت‌های رابط کاربری
- نمایش رکوردها به ترتیب اولویت به کمک jQuery UI sortable در ASP.NET MVC
- jQuery UI Sortable
-Categorized search result with jQuery UI Autocomplete
- jQuery UI Slider
-rtl jQuery UI Slider
-jquery UI Sortable with table and tr width  
jQuery Validation اعتبار سنجی سمت کلاینت
-مشکل اعتبار سنجی jQuery validator در Bootstrap tabs
-نمایش خطاهای اعتبارسنجی سمت کاربر ASP.NET MVC به شکل Popover به کمک Twitter bootstrap
toastr نمایش پیام و اطلاع رسانی

PersianDatePicker یک DatePicker شمسی کم حجم 
-PersianDatePicker یک DatePicker شمسی به زبان JavaScript که از تاریخ سرور استفاده می‌کند
CKEDITOR ادیتور متن
-استفاده از ادیتور CKEditor در صفحات ASP.NET
-یکپارچه سازی CKEditor با Lightbox
Roxy Fileman مدیریت فایل ها  -افزونه مدیریت فایل‌های رایگان Roxy FileMan برای TinyMce و CkEditor  
Magnific Popup نمایش عکس‌ها به صورت پاپ آپ

Select2 تغییر شکل drop down list‌ها برای انتخاب گزینه‌ها

jqGrid v4.6 نمایش اطلاعات در قالب جدول
- آموزش jqGrid
Bootstrap Star Rating امتیاز دهی ستاره ای
-پیاده سازی امتیاز دهی ستاره‌ای به مطالب به کمک jQuery در ASP.NET MVC
jQuery File Upload Plugin آپلود فایل به صورت AJAX ای

HIGHCHARTS نمایش نمودار

jQuery Number Plugin برای فرمت کردن اعداد

X-editable ویرایش اطلاعات به صورت inline
-قابل ویرایش کننده‌ی فوق العاده x-editable ؛ قسمت اول  
bootstrap-confirmation نمایش فرم تایید در قالب popover

PathJS برای تغییر URL صفحه برای اعمال Ajax ای 
-پیاده سازی دکمه «بیشتر» یا «اسکرول نامحدود» به کمک jQuery در ASP.NET MVC  

فریمورک‌های CSS:
 
فناوری یا کتابخانه
 توضیحات  
 مقالات مرتبط  
 Bootstrap 3.x 
 فریم ورک پایه ای css سایت
 - Bootstrap 3 RTL Theme
- Twitter Bootstrap
-سازگارسازی کلاس‌های اعتبارسنجی Twitter Bootstrap 3 با فرم‌های ASP.NET MVC 
-ساخت قالب‌های نمایشی و ادیتور دکمه سه وضعیتی سازگار با Twitter bootstrap در ASP.NET MVC
-نمایش اخطارها و پیام‌های بوت استرپ به کمک TempData در ASP.NET MVC
 AdminLTE 
 قالب مدیریت سایت
 - نسخه راستچین شده AdminLTE 2.2.1
Animate.css   انیمیشن‌های css3 سایت

Font Awesome   پک آیکون‌های برداری

Awesome Bootstrap Checkbox   زیبا سازی چک باکس ها

فونت فارسی وزیر   قلم فارسی



لطفا برای طرح سؤالات و پیشنهادات خود و جهت مدیریت بهتر آن‌ها، از قسمت اختصاصی این پروژه در سایت استفاده نمائید.
  • #
    ‫۸ سال و ۶ ماه قبل، دوشنبه ۹ فروردین ۱۳۹۵، ساعت ۱۵:۴۱
    با تشکر از کار خوب شما و اشتراک گذاری آن. انجام چنین پروژه ای برای شما چقدر زمانبر بوده؟
    • #
      ‫۸ سال و ۶ ماه قبل، سه‌شنبه ۱۰ فروردین ۱۳۹۵، ساعت ۱۶:۰۰
      خواهش می‌کنم؛ حدودا دو هفته‌ی کاری.
  • #
    ‫۸ سال و ۶ ماه قبل، دوشنبه ۹ فروردین ۱۳۹۵، ساعت ۱۵:۴۹
    آقای نصیری امکانش هست موارد استفاده شده در سایت جاری رو عنوان کنید ؟
    • #
      ‫۸ سال و ۶ ماه قبل، دوشنبه ۹ فروردین ۱۳۹۵، ساعت ۱۵:۵۳
      در فوتر سایت لینکش هست؛ اینجا.
  • #
    ‫۸ سال و ۶ ماه قبل، دوشنبه ۹ فروردین ۱۳۹۵، ساعت ۱۵:۵۹
    به نظرم از یک date picker هماهنگ با بوت استرپ استفاده بشه بهتره. مثل MD.BootstrapPersianDateTimePicker  
    • #
      ‫۸ سال و ۶ ماه قبل، سه‌شنبه ۱۰ فروردین ۱۳۹۵، ساعت ۱۶:۰۱
      ممنون بابت معرفی، از وجود چنین date picker خوبی بی خبر بودم. حتما در پروژه استفاده خواهم کرد.
  • #
    ‫۸ سال و ۶ ماه قبل، دوشنبه ۹ فروردین ۱۳۹۵، ساعت ۱۶:۳۵
    با توجه به اینکه از بسته نیوگت DNTScheduler  استفاده شده، فکر کنم نیازی به پروژه IrisStore\Scheduler نباشه چون به روز شده‌اش در بسته نیوگت هست.
    • #
      ‫۸ سال و ۶ ماه قبل، سه‌شنبه ۱۰ فروردین ۱۳۹۵، ساعت ۱۶:۰۹
      البته در سطح Solution این پروژه حذف شده بود ولی در سطح فیزیکی فراموش کرده بودم که حذفش کنم.
      ممنون و مخزن کد اصلاح شد.
  • #
    ‫۸ سال و ۶ ماه قبل، سه‌شنبه ۱۰ فروردین ۱۳۹۵، ساعت ۱۷:۳۲
    با وجود این که پروژه‌های موجود در بخش پروژه‌های سایت ، کمتر همکاری و یا بازخورد را داشته ولی باز هم قرار دادن آن در بخش مذکور به نظرم برای ارائه بازخورد‌ها و مدیریت راحت آنها توسط خودتان ، بهتر خواهد بود؛  البته گیت هاب هست ولی اکثرا هیچ بازخوردی در آنجا از جانب دوستان ایرانی ارائه نمیشود.
    رعایت نکته ای که در مورد بهبود کارایی EF  چندی پیش در سایت توسط آقای هاشم زاده ارئه شد هم میتواند مفید باشد.برای مثال تغییر در کدهای زیر:
    .Skip(page * pageSize).Take(pageSize)

    • #
      ‫۸ سال و ۶ ماه قبل، سه‌شنبه ۱۰ فروردین ۱۳۹۵، ساعت ۱۹:۲۶
      حتما در فرصت مناسبی این کار را انجام خواهم داد.
      نکته‌ی ذکر شده را در پروژه‌های اخیرم رعایت کردم و حتما آن را در این پروژه نیز اعمال خواهم کرد.
       ممنون
  • #
    ‫۸ سال و ۶ ماه قبل، سه‌شنبه ۱۰ فروردین ۱۳۹۵، ساعت ۲۰:۴۴
    سلام؛ اول تشکر میکنم از شما بابت اینکه سورستون رو در اختیار بقیه قرار میدین. من خودم تازه شروع کردم دارم سمت سرور و MVC کار میکنم.
    الان این پروژه رو دانلود کردم و از طریق Enabled Nuget .... تمام رفرسن هارو اضافه کردم ولی وقتی میخام پروژه رو بیلد کنم با خطاهای زیر مواجه میشم

    اون قضیه $ چیه پشت رشته‌ها قرار دادین؟ 
  • #
    ‫۸ سال و ۴ ماه قبل، شنبه ۲۵ اردیبهشت ۱۳۹۵، ساعت ۰۲:۲۶
    رمز ورود به پنل مدیریتی چی هست؟
    • #
      ‫۸ سال و ۴ ماه قبل، شنبه ۲۵ اردیبهشت ۱۳۹۵، ساعت ۰۳:۵۴
      username: demo@email.com
      pass: 123demo123
  • #
    ‫۸ سال و ۴ ماه قبل، شنبه ۲۵ اردیبهشت ۱۳۹۵، ساعت ۱۶:۲۶
    من متوجه پوشه بندی هایی که در پروژه هست نمیشم. چه الزامی هست که باید این طور پوشته بندی بشه. منظورم پوشه‌های
    Iris.DataLayer
    ...
    • #
      ‫۸ سال و ۴ ماه قبل، شنبه ۲۵ اردیبهشت ۱۳۹۵، ساعت ۱۶:۵۶
      مسیر راه Entity framework code-first  را مطالعه کنید. یک قسمت لایه بندی هم دارد.  
  • #
    ‫۷ سال و ۶ ماه قبل، سه‌شنبه ۲۴ اسفند ۱۳۹۵، ساعت ۰۱:۰۴
    با سلام و تشکر بابت این پروژه سورس باز
    ولی چرا لینک مربوط به مشاهده نمونه آنلاین فروشگاه آیریس در ابتدای صفحه کار نمی‌کند
  • #
    ‫۷ سال و ۳ ماه قبل، دوشنبه ۲۹ خرداد ۱۳۹۶، ساعت ۰۲:۴۳
    جهت اطلاع سبد خرید هم به پروژه افزوده شد.
    • #
      ‫۷ سال و ۳ ماه قبل، دوشنبه ۲۹ خرداد ۱۳۹۶، ساعت ۰۳:۳۰
      با تشکر 
      امکانش هست توضیح بدین چرا برای سبد خرید از کوکی‌ها استفاده نکردین؟ در حقیقت مزیت استفاده از بانک چیه ؟
      • #
        ‫۷ سال و ۳ ماه قبل، دوشنبه ۲۹ خرداد ۱۳۹۶، ساعت ۱۵:۱۳
        برای کاربر هایی که وارد سایت نشده اند، کد کالا‌ها درون localstorage ذخیره می‌شود که پس از ورود به سیستم امکان بازیابی کالا‌های انتخاب شده از سرور وجود داشته باشد.
  • #
    ‫۷ سال و ۲ ماه قبل، سه‌شنبه ۳ مرداد ۱۳۹۶، ساعت ۱۹:۰۵
    سلام چرا وقتی پروژه رو روی هاست آپلود می‌کنیم سایت اتوماتیک ریدارکت میشه به یه سایت دیگه و دلیل استفاده از این کد توی web.config چیه ؟
    <rewrite>
          <rules>
            <rule name="Enforce WWW" stopProcessing="true">
              <match url=".*" />
              <conditions>
                <add input="{CACHE_URL}" pattern="^(.+)://(?!www)(.*)" />
                <add input="{HTTP_HOST}" pattern="localhost" negate="true" />
              </conditions>
              <action type="Redirect" url="http://www.website.ir/{R:0}" redirectType="Permanent" />
            </rule>
          </rules>
        </rewrite>
    • #
      ‫۶ سال و ۸ ماه قبل، جمعه ۲۲ دی ۱۳۹۶، ساعت ۱۵:۰۵
      در توضیحات ذکر کردین "پیاده سازی سبد خرید و خرید آنلاین " انجام نشده و نیاز به پیاده سازی داره . درسته ؟
      آیا بیس این پروژه در vs2017  مشکلی نداره ؟
      تشکر
      • #
        ‫۶ سال و ۸ ماه قبل، جمعه ۲۲ دی ۱۳۹۶، ساعت ۱۵:۵۳
        در این کامنت ذکر کردم که سبد خرید نیز اضافه شده است.
        نه با ویژوال استادیود 2017 مشکلی ندارد و تست شده است.
  • #
    ‫۶ سال و ۸ ماه قبل، دوشنبه ۲۵ دی ۱۳۹۶، ساعت ۲۲:۵۴
    سلام
    در این پروژه در قسمت "مدیریت گروه‌های کالاها" از یک jqGrid استفاده شده است. این کامپوننت یک مشکل جزئی دارد و آن زمانی رخ می‌دهد که گزینه جدید را انتخاب کرده و عنصری را به جدول اضافه کنیم. پس از اضافه شدن عنصر دکمه‌های حذف و ویرایش از جلو تمامی سطر‌ها حذف می‌شود.
    قبل از عملیات اضافه کردن:

    بعد از عملیات اضافه کردن:

    لطفا جهت حل مشکل راهنمائی بفرمائید.

  • #
    ‫۶ سال و ۳ ماه قبل، جمعه ۴ خرداد ۱۳۹۷، ساعت ۱۷:۴۹
    با سلام و خسته نباشید؛ بابت نمونه فروشگاه و البته نمونه سورس پروژه جهت هر کاری ممنون و سپاس فراوان. یک مورد من میخواهم از وب سرویس در این پروژه استفاده کنم با خطا مواجه میشم اگر امکانش هست بنده رو راهنمایی بفرمایید

  • #
    ‫۵ سال و ۸ ماه قبل، چهارشنبه ۱۲ دی ۱۳۹۷، ساعت ۰۰:۲۴
    موقع کلیک روی تاریخ، قیمت و تخفیف که به صورت x-editable هستند این پیغام خطا در کنسول کروم و فایرفاکس ظاهر می‌شود:


    ...... 
    Uncaught TypeError: Cannot read property 'settings' of undefined

    در کامنت‌ها به راه حل اشاره شده است:
    Issues with Jquery unobtrusive 

    راه حل :
    $('#username').on('shown', function() {
        var $innerForm = $(this).data('editable').input.$input.closest('form');
        var $outerForm = $innerForm.parents('form').eq(0);
        $innerForm.data('validator', $outerForm.data('validator'));
    });
  • #
    ‫۵ سال و ۶ ماه قبل، دوشنبه ۲۷ اسفند ۱۳۹۷، ساعت ۲۲:۴۷
    حذف تگ‌های htlml و normalization توسط متد   RemoveHtmlTags  به درستی انجام نمی‌شود و در برخی موارد کلمات جدا از هم به یکدیگر متصل می‌شوند.  

    راه حل:
            public static string RemoveHtmlTags(this string str)
            {
                if (string.IsNullOrWhiteSpace(str))
                {
                    return string.Empty;
                }
              
               //remove html tags by HtmlAgilityPack
                HtmlDocument htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(str);
               
               // normalization
                return Regex.Replace(htmlDoc.DocumentNode.InnerText, @"&nbsp;|&zwnj;|(\n)\s*", " ").Trim();
            }
  • #
    ‫۵ سال و ۲ ماه قبل، جمعه ۳۱ خرداد ۱۳۹۸، ساعت ۱۸:۵۰
     تخفیف در بخش کالاهای مشابه  نمایش داده نمی‌شود. زیرا در ایندکس لوسین لیست تخفیف‌ها وارد نشده است. لیست تخفیف‌ها به ویو  ارسال می‌شود و در آنجا بررسی می‌شود که تخفیف فعال وجود دارد یا خیر! 

    راه حل بنده
    کنترلر:
                // در این قسمت discounts
                // در کالاهای مشابه اضافه نشده است
                var serchResult = LuceneIndex.GetMoreLikeThisProjectItems(id)
                        .Where(item => item.Category == "کالا‌ها").Skip(1).Take(8).ToList();
    
                List<ProductWidgetViewModel> productToDel = new List<ProductWidgetViewModel>();
                if (serchResult.Count > 0)
                {
                    foreach (var product in serchResult)
                    {
                        if (product.Discount > 0)
                        {
                            var resul = await _productService.GetProductDiscount(product.Id);
                            // محصول در دیتابیس وجود نداشته
                            if (resul == null)
                            {
                                productToDel.Add(product);
                                //error
                                //serchResult.Remove(product);
                            }
                            else if (resul.Discount != 0)
                            {
                                product.Discounts = new List<ProductPageDiscountWidgetViewModel>();
                                product.Discounts.Add(resul);
                            }
                        }
                    }
                }
    
                foreach (var product in productToDel)
                {
                    serchResult.Remove(product);
                }
                ViewData["SimilarProducts"] = serchResult;

    سرویس:
     public async Task<ProductPageDiscountWidgetViewModel> GetProductDiscount(int productId)
            {
                var product = await _products.FirstOrDefaultAsync(p => p.Id == productId);
                //by SYA
                // در ایندکس هست اما در دیتابیس نیست product == null
    
                if (product == null)
                {
                    return null;
                }
                else if (product.Discounts == null)
                {
                    return new ProductPageDiscountWidgetViewModel { Discount = 0 };
                }
                //_mappingEngine.Map<ProductDiscount, ProductPageDiscountWidgetViewModel>(
                //    product.Discounts.OrderByDescending(p => p.EndDate).FirstOrDefault());
                foreach (var dic in product.Discounts.OrderByDescending(p => p.StartDate).ToList())
                {
                    if (dic.Discount > 0 && dic.EndDate >= DateTimeExtentionService.NowIranZone())
                    {
                        return _mappingEngine.Map<ProductDiscount, ProductPageDiscountWidgetViewModel>(dic);
                    }
                }
                return new ProductPageDiscountWidgetViewModel { Discount = 0 };
            }

    در موقع نوشتن کد حالتی را در نظر گرفتم که کالا در ایندکس لوسین وجود داشته باشد اما در دیتابیس نه!


    • #
      ‫۵ سال و ۲ ماه قبل، شنبه ۱ تیر ۱۳۹۸، ساعت ۱۳:۲۲
      ممنون بابت رفع باگ ها، ممنون میشم اگر تغییرات خودتون را به صورت pull request نیز ارسال کنید.
      با تشکر