JeeCMS使用心得

2023-3-15 15:32

我先说下总结,从使用上来看,jeecms功能看着很多,但是核心功能做的不彻底,不够强,只能应付一般性使用,复杂的要求就比较难实现,甚至还得自己改代码。

一、部署包下载

二、源代码下载

三、文档下载

这三个的下载都在官方论坛的帖子中,需要先注册并回帖。正版系统和正版源码等购买后官方会提供。

四、源码运行

源代码运行需要先配置好数据库,数据库需要自己从部署包中获取到脚本,然后再执行。我用的是centos下的mysql数据库,源代码运行和安装部署运行都报错,查找问题发现数据库中的所有QRTZ表的表名大小写问题。在linux下mysql默认是区分大小写的。脚本中的表名都是小写的,把表名字都改成大写就可以了。

当前免费版后台首页是 http://localhost:8083/jeecms/index.html , 网站的首页是 http://localhost:8083 需要后台对站点进行设置,设置成localhost。初始登录账号 system,密码 123456

五、安装部署

安装部署中碰到了首页打不开的问题,或者说首页打开就是tomcat的首页。去掉tomcat配置文件中的首页的定义解决。配置完成后同样需要进入后台后对站点进行设置。

六、系统的使用

主要使用的功能有如下几个:

  1. 系统/模型管理/内容模型管理:创建详情页需要的数据,这里制作的表单也就是编辑人员发布信息的表单页面。我在这里创建了“解决方案“模型,里面增加了banner字段。解决方案栏目下的所有子页面都用这个模型。
  2. 配置/模板管理,模板维护在这里。
  3. 栏目管理,我在这里创建了一二级栏目结构。一级栏目“首页“、”解决方案“、”产品“、”服务“等,按照导航的结构来做的定义。其中二级栏目定义了模板,使用的是solution.html模板,这样点击二级栏目链接跳转的页面会使用这个模板来生成。另外栏目需要设置模型。
  4. 内容管理,对对应栏目发布内容。

 

七、模板说明

模板常用的是内容模板和栏目模板,分别用于显示栏目页面和内容页面。在栏目模板中,我已经完成了首页的header的菜单导航部分。采用的是把导航设置成了两级栏目的方式,从菜单导航点进去的各个方案产品等页面都是内容页。

一些代码说明:

                <div id="channelIds" ref="channelIds" style="display: none;">
                    [@cms_channel_list siteId='1']
                    [#list tag_list as a]
                    <span>${a.id}</span>
                    [/#list]
                    [/@cms_channel_list]
                </div>
 

上面的代码是获取所有一级频道列表,网站最上面的一条,下面的代码是生成弹出的菜单导航代码。根据导航的结构,做了三层循环。代码参见portal-html项目的index-1.html页。

                [@cms_channel_list siteId='1']
                [#list tag_list as a]
                [@cms_channel id='${a.id}']
                <div class="base-header-menu" v-if="showMenu && iSelectMenuIndex == ${a.id}" @click="clickBlack">
                    <div class="menu-container_" @mouseleave="clickBlack" @click.stop="clickContent">
                        <div class="left animated  slideInLeft" >
                            <div class="content-container block-anim-left-to-right">
                                <div class="title">
                                    ${tag_bean.name}
                                </div>
                                <div class="description">
                                    ${tag_bean.description!""}
                                </div>
                            </div>
                        </div>
                        <div class="right block-anim-right-to-left animated slideInRight">
                            <div
                                :class="{
                                'content-container': iSelectMenuIndex == channelIds[1] || iSelectMenuIndex == channelIds[3],
                                'content-container2': iSelectMenuIndex == channelIds[2],
                                'content-container3': iSelectMenuIndex == channelIds[4]}">
                                [@cms_channel_list siteId='1' parentId='${tag_bean.id}']
                                [#list tag_list as b]
                                <div class="list">
                                    <div class="list-title">${b.name}</div>
                                    <div class="list-item-container">
                                        <!-- <div class="list-item" v-for="(child, child_index) in item.child"
                                            :key="child.cn" @click="clickDescription(index, child_index)">
                                            {{ child.cn }}
                                        </div> -->
                                       
                                        [@cms_content_list count='8' channelId='${b.id}']
                                        [#list tag_list as a]
                                        <a class="list-item"
                                            href="${a.url}">
                                            ${a.title!}
                                        </a>
                                        [/#list]
                                        [/@cms_content_list]
                                    </div>
                                </div>
                                [/#list]
                                [/@cms_channel_list]
                                </div>
                            <img src="${tag_bean.iconUrl}" class="icon" />
                        </div>
       
                        <!-- <div class="right block-anim-right-to-left animated slideInRight">
                            <div :class="{
                            'content-container': iSelectMenuIndex == 1 || iSelectMenuIndex == 3,
                            'content-container2': iSelectMenuIndex == 2,
                            'content-container3': iSelectMenuIndex == 4}">
                                <div class="list" v-for="(item, index) in header_tab_title[iSelectMenuIndex].list"
                                    :key="item.cn">
                                    <div class="list-title">{{ item.cn }}</div>
                                    <div class="list-item-container">
                                        <div class="list-item" v-for="(child, child_index) in item.child"
                                            :key="child.cn" @click="clickDescription(index, child_index)">
                                            {{ child.cn }}
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <img src="" class="icon" />
                        </div> -->
                    </div>
                </div>
                [/@cms_channel]
                [/#list]
                [/@cms_channel_list]

 

Content/solution.html模板中,主要代码如下,参看项目源代码中的solution-1.html

                <#assign json2=content.txtAttrCleanHtml.content?eval/>
                <#list json2 as block>
                <div class="content-base">
                  <#if block.blockType == 'description'>
                  <div :class="{ 'product-word-base': true, 'font-background': ${(block.background == 'gray') ? string("true","false")} }" v-scroll="'anim-bottom-to-top'">
                    <div class="description">
                      <div :class="{
                        'description-content': true,
                        'font-bold': ${(block.type == 'bold') ? string("true","false")},
                        'font-align-center': ${(block.align == 'center') ? string("true","false")},
                        'font-align-left': ${(block.align != 'center') ? string("true","false")},
                        'font-width-small': ${(block.size == 'small') ? string("true","false")},
                        'font-width-normal': ${(block.size == 'normal') ? string("true","false")},
                        'font-margin-line': ${(block.margin == 'line') ? string("true","false")},
                        'font-color-gray': ${(block.background == 'gray') ? string("true","false")}
                        }"
                      >
                        <#if block.cn??>
                        <span>
                          ${block.cn?html}
                          <#if block.sub_cn??>
                          <span class="font-small">${block.sub_cn?html}</span>
                          </#if>
                        </span>
                        </#if>
                      </div>
                    </div>
                  </div>
                  <#elseif block.blockType == 'timeline'>
                  <div :class="{'product-timeline-base': true, 'gray': ${(block.background == 'gray') ? string('true','false')} }"
                    v-scroll="'anim-bottom-to-top'"
                  >
                    <div class="title">${block.title.cn?html}</div>
                   
                    <div class="timeline">
                      <div class="top">
                        <#list block.timeline as tl>
                        <#if (tl?index) == 0 || (tl?index) == 2>
                        <div class="timeline-item-base">
                          <img src="/images/asset/arrow_top.png" class="arrow" v-if="false" />
                          <div class="bg">
                            <div class="title" style="margin-left: 0;">${tl.title.cn?html}</div>
                            <div class="description">${tl.description.cn?html}</div>
                          </div>
                          <img
                            src="/images/asset/arrow_bottom.png"
                            class="arrow"
                            v-if="true"
                          />
                        </div>
                        </#if>
                        </#list>
                      </div>
                      <img src="/images/asset/scrollbar.png" class="image-bar" />
                      <div class="bottom">
                        <#list block.timeline as tl>
                        <#if (tl?index) == 1 || (tl?index) == 3>
                        <div class="timeline-item-base">
                          <img src="/images/asset/arrow_top.png" class="arrow" v-if="true" />
                          <div class="bg">
                            <div class="title" style="margin-left: 0;">${tl.title.cn?html}</div>
                            <div class="description">${tl.description.cn?html}</div>
                          </div>
                          <img
                            src="/images/asset/arrow_bottom.png"
                            class="arrow"
                            v-if="false"
                          />
                        </div>
                        </#if>
                        </#list>
                      </div>
                    </div>
 
                  </div>
                  <#elseif block.blockType == 'menu_bottom'>
                  <div
                    :class="{ 'product-swiper-base': true, gray: ${(block.background == 'gray') ? string('true','false')} }">
                    <div class="menu-container" v-scroll="'anim-bottom-to-top'">
                      <#list block.menu_bottom as item>
                      <div
                          :class="{
                          'item-2': ${(block.line_count == '2') ? string('true','false')},
                          'item-3': ${(block.line_count == '3') ? string('true','false')},
                          'item-4': ${(block.line_count == '4') ? string('true','false')}
                          }"
                      >
                        <div class="solution-detail-container">
                          <img src="/images/asset/语言康复.png" class="icon" />
                          <div class="title">${item.title.cn?html}</div>
                          <div
                            :class="{ 'description': true, 'description-phone': isphone }"
                            v-html="item.description.cn"
                            @click="showDialog"
                          >${item.description.cn?html}</div>
                        </div>
                      </div>
                      </#list>
                    </div>
                    <#if block.contact == 'show'>
                    <div
                      v-scroll="'anim-bottom-to-top'"
                      :class="{
                          'contact-btn': true
                      }"
                      @click="clickContact"
                      >
                      联系我们
                    </div>
                    </#if>
                  </div>
                  </#if>
                </div>
                </#list>

 

内容管理中如下做发布,将项目的data.js文件中的cmsData的值拷贝出来,压缩去空格后,录入到内容管理的正文中发布,页面模板通过解析这个json字符串,格式化输出页面内容。

json数据大概是这样的数组

[{
  "blockType": "description/timeline/menu_bottom",
  "type": "bold",
  "align": "center",
  "size": "small/normal",
  "margin": "line",
  "background": "gray",
  "cn": "这是文本内容",
  "sub_cn": "这是小字部分"
}]

其实让网站维护人员填写json数据不是好办法,最好使用带有提示性的表单来完成维护操作,但是jeecms的表单功能太简单了,没法实现复杂的定制化数据结构,比如我一个页面可能有多个块构成,这些块可能是各种特效效果,每种特效需要的数据项不同,需要设置复杂点的表单来让用户录入数据。当前只能录入json。奇葩的是多行文本只能50字符好像,必须得用自带的正文,而自带的正文录入json会自动html编码化,并且无法使用FreeMarker解码,造成无法实现json数据获取。我把源代码做了些调整,txtAttrCleanHtml 改成了Html解码功能,但是录入的json还是会有问题,说一个空格字符不识别。那我就先用工具把json去空格,然后再录入就没问题了,太曲折。最后总结下jeecms缺点:内容模型不够强,没有数组类型,不知条件显示,比如页面上一个选项关联一个显示块,让表单变动态显示。应对复杂业务场景表单显示效果很差。没有足够好的内容提醒, 没有事件和和基于事件的默认值等。字段长度也很有问题,多行文本最多50字,我没记错的话。

 

点击:loading..
收藏到:中国收客网
评论