精华内容
下载资源
问答
  • 金蝶二次开发的常见类型

    千次阅读 2018-01-25 14:17:20
    常用开发方式:业务单据插件 业务单据插件用于进行一些复杂的业务计算。 常用开发方式三:触发器 用触发器处理一些简单的数据提取、反写。 常用开发方式四:存储过程 用SQL存储过程处理一些复杂的数据提取、...

    常用开发方式一:基础资料插件
    客户、供应商、物料等基础资料录入界面可以控制编码的生成规则以及任意字段的生成方式。
    常用开发方式二:业务单据插件
    业务单据插件用于进行一些复杂的业务计算。
    常用开发方式三:触发器
    用触发器处理一些简单的数据提取、反写。
    常用开发方式四:存储过程
    用SQL存储过程处理一些复杂的数据提取、反写。如销售出库单表头费用在出库单审核时,自动生成对应的其他应付单等关联单据。
    常用开发方式五:复杂报表
    如一些复杂的对账单,需要通过代码来提取生成,导出至现有格式的EXCEL内或生成个性化很强的报表格式。
    用开发方式六:外部业务数据生成凭证
    一些使用非金蝶ERP的系统,可以把外部业务数据生成金蝶凭证。

    展开全文
  • 想必大家都听说过微信二次开发,那么什么是微信二次开发呢?如何进行微信二次开发呢?下面就由艺形艺意工作室创始人黎想将从3W角度为大家详细介绍什么是微信二次开发,如何进行微信二次开发。那么也请大家带着这个...

    近年来,随着微信业务的突飞猛进,微信可谓是开创了中国即时通讯业的又一先河。想必大家都听说过微信二次开发,那么什么是微信二次开发呢?如何进行微信二次开发呢?下面就由艺形艺意工作室创始人黎想将从3W角度为大家详细介绍什么是微信二次开发,如何进行微信二次开发。那么也请大家带着这个问题和我一起看下去!

    因为微信庞大的用户群,间接意义上是企业搭建了一个良好的营销推广平台,所以许多个人、企业都纷纷借助微信开展了属于自己的微信模块业务,最常见的一类便是微商,这也是最基础的一类。

    什么是微信二次开发?

    所谓的微信二次开发,其实就是在微信上面建设自己需要的一些板块,而这些板块是原先并没有的,微信团队留给用户的一块开垦地,也就是微信二次开发。例如大转盘、刮刮乐等这些功能也属于二次开发,微信二次开发是微信营销的营销神器,通过开发一些互动功能,促进客户的粘度,跟客户一对一的交流了解客户最真实的需求。

    为什么要进行微信二次开发?

    如果微信公众号不进行开发,只是用免费的功能每天发布一些广告、新闻、动态长此以往客户潜意识就认为你这打广告没有任何的实力。微信公众号认证后可以加上企业简介、企业动态、产品图片、团队介绍等这些栏目,一:可以向可以展示我们公司的实力,二:可以提高客户对我们的信任度,三:可以和客户进行互动不再是需要你点击1或是2等待系统给你回复了。其次:可以加入微官网、微活动、微服务、微相册、会员系统、留言系统等可以更好的跟客户交流,了解客户的需求以便达成交易。

    微信二次开发的意义何在?

    1、通过微信公众平台的二次开发,将企业品牌展示给微信用户,减少宣传成本,建立企业与消费者、客户的一对一互动和沟通,将消费者接入企业CRM系统,进行促销、推广、宣传、售后等,形成了一种主流的线上线下微信互动营销方式。
    2、再小的个体也有自己品牌,提升企业品牌知名度
    3、顺应时代,积极创新

    微信营销是互联网经济时代企业营销模式的又一次创新,是伴随着微信的火热而兴起的一种新型网络营销模式。微信突破了时间、距离的限制,用户注册微信后,可与周围同样注册的“朋友”形成一种联系,用户订阅自己所需的信息,商家通过提供用户需要的信息,推广自己的产品,从而实现点对点的精准营销。
    微信营销主要体现在商家通过微信公众平台,结合微信会员卡展示商家微官网、微会员、微推送、微支付、微活动,已经形成了一种主流的线上线下微信互动营销方式。

    最后,在和大家分享一下微信二次开发常用功能有哪些?

    (一)微信官网
    1、公司介绍:支持多级分类;
    2、产品展示:产品支持多图显示,手指滑动浏览图片;
    3、新闻资讯:对接微信公众平台消息推送;
    4、联系方式:LBS地图位置标注,点击电话号码直接拨打;
    5、信息推送:以微信官方规定的消息推送为标准

    (二)微信客服
    1、智能客服:实现多个人工客服在线与微信公众平台客户沟通;
    2、LBS位置服务:用户经过微信提供位置,公众平台自动应答离用户最近的地方;
    3、建议/投诉/售后:微信平台内嵌售后服务表单。

    (三)微信商城
    1、在线订购:支持现有商城系统进行对接;
    2、会员系统:支持现有会员系统进行对接;
    3、在线支付:支持在线支付功能,若无需在线支付,则只记录订单信息与流程。

    2018年9月30日,即日起至12月底,用户在韩国、日本、新加坡、泰国、澳大利亚、新西兰等地的微信支付合作门店,再次彰显了微信的未来发展趋势是势不可挡!

    展开全文
  • 二次排序  任务描述 过程分析 代码 执行结果 倒排索引  任务描述 设计思路 代码 执行过程 执行结果   一次排序 熟悉MapReduce的人都知道,排序是MapReduce的天然特性!在数据达到reducer之前...

    目录

    一次排序

    MapReduce的默认排序规则

    Map、Reduce任务中Shuffle和排序的过程

    流程分析

    任务描述

    代码

    执行结果

    二次排序 

    任务描述

    过程分析

    代码

    执行结果

    倒排索引 

    任务描述

    设计思路

    代码

    执行过程

    执行结果


     

    一次排序

    熟悉MapReduce的人都知道,排序是MapReduce的天然特性!在数据达到reducer之前,MapReduce框架已经对这些数据按键排序了。

     

    MapReduce的默认排序规则

    它是按照key值进行排序的,如果key为封装的int为IntWritable类型,那么MapReduce按照数字大小对key排序;

    如果Key为封装String的Text类型,那么MapReduce将按照数据字典顺序对字符排序。

     

    Map、Reduce任务中Shuffle和排序的过程

    流程分析

    1. Map端:

    (1)每个输入分片会让一个map任务来处理,默认情况下,以HDFS的一个块的大小(默认为64M)为一个分片,当然我们也可以设置块的大小。map输出的结果会暂且放在一个环形内存缓冲区中(该缓冲区的大小默认为100M,由io.sort.mb属性控制),当该缓冲区快要溢出时(默认为缓冲区大小的80%,由io.sort.spill.percent属性控制),会在本地文件系统中创建一个溢出文件,将该缓冲区中的数据写入这个文件。

    (2)在写入磁盘之前,线程首先根据reduce任务的数目将数据划分为相同数目的分区,也就是一个reduce任务对应一个分区的数据。这样做是为了避免有些reduce任务分配到大量数据,而有些reduce任务却分到很少数据,甚至没有分到数据的尴尬局面。其实分区就是对数据进行hash的过程。然后对每个分区中的数据进行排序,如果此时设置了Combiner,将排序后的结果进行Combia操作,这样做的目的是让尽可能少的数据写入到磁盘。

    (3)当map任务输出最后一个记录时,可能会有很多的溢出文件,这时需要将这些文件合并。合并的过程中会不断地进行排序和combia操作,目的有两个:①尽量减少每次写入磁盘的数据量。②尽量减少下一复制阶段网络传输的数据量。最后合并成了一个已分区且已排序的文件。为了减少网络传输的数据量,这里可以将数据压缩,只要将mapred.compress.map.out设置为true就可以了。

    (4)将分区中的数据拷贝给相对应的reduce任务。有人可能会问:分区中的数据怎么知道它对应的reduce是哪个呢?其实map任务一直和其父TaskTracker保持联系,而TaskTracker又一直和JobTracker保持心跳。所以JobTracker中保存了整个集群中的宏观信息。只要reduce任务向JobTracker获取对应的map输出位置就ok了哦。

    到这里,map端就分析完了。那到底什么是Shuffle呢?Shuffle的中文意思是“洗牌”,如果我们这样看:一个map产生的数据,结果通过hash过程分区却分配给了不同的reduce任务,是不是一个对数据洗牌的过程呢?

    2.Reduce端:

    (1)Reduce会接收到不同map任务传来的数据,并且每个map传来的数据都是有序的。如果reduce端接受的数据量相当小,则直接存储在内存中(缓冲区大小由mapred.job.shuffle.input.buffer.percent属性控制,表示用作此用途的堆空间的百分比),如果数据量超过了该缓冲区大小的一定比例(由mapred.job.shuffle.merge.percent决定),则对数据合并后溢写到磁盘中。

    (2)随着溢写文件的增多,后台线程会将它们合并成一个更大的有序的文件,这样做是为了给后面的合并节省时间。其实不管在map端还是reduce端,MapReduce都是反复地执行排序,合并操作,现在终于明白了有些人为什么会说:排序是hadoop的灵魂。

    (3)合并的过程中会产生许多的中间文件(写入磁盘了),但MapReduce会让写入磁盘的数据尽可能地少,并且最后一次合并的结果并没有写入磁盘,而是直接输入到reduce函数。

     

    任务描述

    现有用户对商品访问情况的数据文件goods_visit1,包含商品id ,点击次数两个字段,内容以“\t”分割,数据内容如下:

    商品id  点击次数
    1010037	100
    1010102	100
    1010152	97
    1010178	96
    1010280	104
    1010320	103
    1010510	104
    1010603	96
    1010637	97

    要求编写mapreduce程序来对商品点击次数实现由低到高的排序。

     

    代码

    package MapReduce.sort;
    
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.mapreduce.Mapper;
    import org.apache.hadoop.mapreduce.Reducer;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    
    import java.io.IOException;
    
    // goods_visit1中包含(商品id ,点击次数)两个字段,内容以“\t”分割
    // 对商品点击次数由低到高进行排序
    public class OneSort {
    
        public static class Map extends Mapper<Object, Text, IntWritable, Text>{
            private static Text goods=new Text();
            private static IntWritable num=new IntWritable();
            @Override
            protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
                String line=value.toString();
                String arr[]=line.split("\t");
                num.set(Integer.parseInt(arr[1]));//把要排序的点击次数字段转化为IntWritable类型并设置为key
                goods.set(arr[0]);//商品id字段设置为value
                context.write(num,goods);//输出<key,value>
            }
        }
    
        // 在数据达到reducer之前,MapReduce框架已经按照key值对这些数据按键排序了,就是shuffle()
        // 如果key为封装的int为IntWritable类型,那么MapReduce按照数字大小对key排序
        // 如果Key为封装String的Text类型,那么MapReduce将按照数据字典顺序对字符排序
        // 所以一般在map中把要排序的字段使用IntWritable类型,作为key,不排序的字段作为value
        public static class Reduce extends Reducer<IntWritable, Text, IntWritable, Text>{
            @Override
            protected void reduce(IntWritable key, Iterable <Text> values, Context context) throws IOException, InterruptedException {
                for(Text value : values){
                    context.write(key,value);
                }
            }
        }
    
        public static void main(String[] args) throws Exception {
            Job job = Job.getInstance();
            job.setJobName("OneSort");
            job.setJarByClass(OneSort.class);
    
            job.setMapperClass(Map.class);
            job.setReducerClass(Reduce.class);
            job.setOutputKeyClass(IntWritable.class);
            job.setOutputValueClass(Text.class);
    
            Path in = new Path("hdfs://localhost:9000/mr/in/goods_visit1");
            Path out = new Path("hdfs://localhost:9000/mr/out/onesort/goods_visit1");
    
            FileInputFormat.addInputPath(job, in);
            FileOutputFormat.setOutputPath(job, out);
    
            System.exit(job.waitForCompletion(true) ? 0 : 1);
        }
    }

     

    执行结果

     

     

     

     

    二次排序 

    在mapreduce操作时,shuffle阶段会多次根据key值排序。但是在shuffle分组后,相同key值的values序列的顺序是不确定的。如果想要此时value值也是排序好的,这种需求就是二次排序。

     

    任务描述

    用户对商品的访问情况记录为goods_visit2表,包含(goods_id,click_num)两个字段。 要求编写MapReduce代码,功能为根据商品的点击次数(click_num)进行降序排序,再根据goods_id升序排序,并输出所有商品。

    数据内容如下:

    goods_id click_num
    1010037	100
    1010102	100
    1010152	97
    1010178	96
    1010280	104
    1010320	103
    1010510	104
    1010603	96
    1010637	97

     

    过程分析

    在Map阶段:

    1.使用job.setInputFormatClass定义的InputFormat将输入的数据集分割成小数据块splites,同时InputFormat提供一个RecordReder的实现。本实验中使用的是TextInputFormat,他提供的RecordReder会将文本的字节偏移量作为key,这一行的文本作为value。这就是自定义Map的输入是<LongWritable, Text>的原因。

    2.然后调用自定义Map的map方法,将一个个<LongWritable, Text>键值对输入给Map的map方法。注意输出应该符合自定义Map中定义的输出<IntPair, IntWritable>。最终是生成一个List<IntPair, IntWritable>。

    3.在map阶段的最后,会先调用job.setPartitionerClass对这个List进行分区,每个分区映射到一个reducer。每个分区内又调用job.setSortComparatorClass设置的key比较函数类排序。可以看到,这本身就是一个二
    次排序。如果没有通过job.setSortComparatorClass设置key比较函数类,则可以使用key实现的compareTo方法进行排序。


    在Reduce阶段:

    1.reducer接收到所有映射到这个reducer的map输出后,也是会调用job.setSortComparatorClass设置的key比较函数类对所有数据对排序。

    2.然后开始构造一个key对应的value迭代器。这时就要用到分组,使用job.setGroupingComparatorClass设置的分组函数类。只要这个比较器比较的两个key相同,他们就属于同一个组,它们的value放在一个value迭代器,
    而这个迭代器的key使用属于同一个组的所有key的第一个key。

    3.最后就是进入Reducer的reduce方法,reduce方法的输入是所有的(key和它的value迭代器)。同样注意输入与输出的类型必须与自定义的Reducer中声明的一致。

     

    代码

    package MapReduce.sort;
    import java.io.*;
    import java.util.StringTokenizer;
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.*;
    import org.apache.hadoop.mapreduce.*;
    import org.apache.hadoop.mapreduce.lib.input.*;
    import org.apache.hadoop.mapreduce.lib.output.*;
    
    // 二次排序
    // goods_visit2表,包含(goods_id,click_num)两个字段
    // 根据商品的点击次数(click_num)进行降序排序,再根据goods_id升序排序,并输出所有商品
    public class SecondarySort
    {
        public static class IntPair implements WritableComparable<IntPair>// 自定义组合key,让类中个每个成员变量都参与计算和比较
        {
            int first;//第一个成员变量
            int second;//第二个成员变量
            public void set(int left, int right) {
                first = left;
                second = right;
            }
            public int getFirst() {
                return first;
            }
            public int getSecond() {
                return second;
            }
    
            @Override
            public void readFields(DataInput in) throws IOException {//反序列化,从流中的二进制转换成IntPair
                first = in.readInt();
                second = in.readInt();
            }
    
            @Override
            public void write(DataOutput out) throws IOException {//序列化,将IntPair转化成使用流传送的二进制
                out.writeInt(first);
                out.writeInt(second);
            }
    
            @Override
            public int compareTo(IntPair o) {// 自定义key比较
                if (first != o.first)
                    return first < o.first ? 1 : -1;
                else if (second != o.second)
                    return second < o.second ? -1 : 1;
                else
                    return 0;
            }
    
            // 由于后面进行了自定义组合key对象的相等比较操作,最好重写hashCode()和equal()方法
            @Override
            public int hashCode(){
                return first * 157 + second;
            }
    
            @Override
            public boolean equals(Object right){
                if (right == null)
                    return false;
                if (this == right)
                    return true;
                if (right instanceof IntPair) {
                    IntPair r = (IntPair) right;
                    return r.first == first && r.second == second;
                }
                else
                    return false;
            }
        }
    
        // 分区函数类代码
        public static class FirstPartitioner extends Partitioner<IntPair, IntWritable>
        {
            @Override
            public int getPartition(IntPair key, IntWritable value,int numPartitions) {
                /**
                 *  数据输入来源:map输出
                 *  @param key map输出键值,自定义组合key
                 *  @param value map输出value值
                 *  @param numPartitions 分区总数,即reduce task个数
                **/
                // 数字的分区写法:
                // 根据自定义key中first(click_num)乘以127取绝对值,再对numPartions取余来进行分区,主要是为实现了第一次排序
                return Math.abs(key.getFirst() * 127) % numPartitions;
            }
        }
    
        // 分组函数类代码,即自定义比较器,自定义二次排序策略
        public static class GroupingComparator extends WritableComparator // 这是一个比较器,需要继承WritableComparator
        {
            protected GroupingComparator() {
                super(IntPair.class, true);
            }
            @Override
            public int compare(WritableComparable w1, WritableComparable w2) {
                // 在reduce阶段,构造一个key对应的value迭代器的时候,只要first相同就属于同一个组,放在一个value迭代器
                IntPair ip1 = (IntPair) w1;
                IntPair ip2 = (IntPair) w2;
                int l = ip1.getFirst();//click_num
                int r = ip2.getFirst();
                return l == r ? 0 : (l < r ? -1 : 1);//比较click_num大小,相等返回0,小于返回-1,大于返回1
            }
        }
    
        // 在Map阶段:
        // 1. 使用job.setInputFormatClass定义的InputFormat将输入的数据集分割成小数据块splites,同时InputFormat提供一个RecordReder的实现。
        //    本实验中使用的是TextInputFormat,他提供的RecordReder会将文本的字节偏移量作为key,这一行的文本作为value。
        //    这就是自定义Map的输入是<LongWritable, Text>的原因。
        // 2. 然后调用自定义Map的map方法,将一个个<LongWritable, Text>键值对输入给Map的map方法。
        //    注意输出应该符合自定义Map中定义的输出<IntPair, IntWritable>。最终是生成一个List<IntPair, IntWritable>。
        // 3. 在map阶段的最后,会先调用job.setPartitionerClass对这个List进行分区,每个分区映射到一个reducer。
        //    每个分区内又调用job.setSortComparatorClass设置的key比较函数类排序。可以看到,这本身就是一个二次排序。
        //    如果没有通过job.setSortComparatorClass设置key比较函数类,则可以使用key实现的compareTo方法进行排序。
    
        // 将map端输出的<key,value>中的key和value组合成一个新的key(称为newKey),value值不变,变成<(key,value),value>
        // 在针对newKey排序的时候,如果key相同,就再对value进行排序。
        public static class Map extends Mapper<LongWritable, Text, IntPair, IntWritable>
        {
            private final IntPair intkey = new IntPair();
            private final IntWritable intvalue = new IntWritable();//相当于int
            public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
                String line = value.toString();
                StringTokenizer tokenizer = new StringTokenizer(line);
                int left = 0;
                int right = 0;
                if (tokenizer.hasMoreTokens())//如果还存在下一个记录
                {
                    left = Integer.parseInt(tokenizer.nextToken());//goods_id
                    if (tokenizer.hasMoreTokens())
                        right = Integer.parseInt(tokenizer.nextToken());//click_num
                    intkey.set(right, left);
                    intvalue.set(left);
                    context.write(intkey, intvalue);//组合为新的键<(key,value),value>,即<(click_num,goods_id),goods_id>
                }
            }
        }
    
    
        // 在Reduce阶段:
        // 1. reducer接收到所有映射到这个reducer的map输出后,也是会调用job.setSortComparatorClass设置的key比较函数类对所有数据对排序
        // 2. 然后开始构造一个key对应的value迭代器。这时就要用到分组,使用job.setGroupingComparatorClass设置的分组函数类
        //    只要这个比较器比较的两个key相同,他们就属于同一个组,它们的value放在一个value迭代器,而这个迭代器的key使用属于同一个组的所有key的第一个key
        // 3. 最后就是进入Reducer的reduce方法,reduce方法的输入是所有的(key和它的value迭代器),同样注意输入与输出的类型必须与自定义的Reducer中声明的一致
        public static class Reduce extends Reducer<IntPair, IntWritable, Text, IntWritable>
        {
            private final Text left = new Text();
            private static final Text SEPARATOR = new Text("------------------------------------------------");
            public void reduce(IntPair key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {
                context.write(SEPARATOR, null);
                left.set(Integer.toString(key.getFirst()));//click_num
                for (IntWritable val : values)//goods_id
                    context.write(left, val);
            }
        }
    
        public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
            Configuration conf = new Configuration();
            Job job = new Job(conf, "SecondarySort");
            job.setJarByClass(SecondarySort.class);
    
            job.setMapperClass(Map.class);
            job.setReducerClass(Reduce.class);
    
            //设置分区函数类,实现第一次排序
            job.setPartitionerClass(FirstPartitioner.class);
    
            // 指定分组排序使用的比较器,默认使用key对象(IntPair)自身的compareTo()方法,实现第二次排序
            job.setGroupingComparatorClass(GroupingComparator.class);
    
            //设置map输出类型
            job.setMapOutputKeyClass(IntPair.class);
            job.setMapOutputValueClass(IntWritable.class);
    
            //设置reduce输出类型
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
    
            job.setInputFormatClass(TextInputFormat.class);
            job.setOutputFormatClass(TextOutputFormat.class);
    
    //        job.setNumReduceTasks(1);//设置reduce  Task的数量,默认是1
    
            String[] otherArgs=new String[]{
                    "hdfs://localhost:9000/mr/in/goods_visit2",
                    "hdfs://localhost:9000/mr/out/secondarysort/goods_visit2"
            };
            FileInputFormat.setInputPaths(job, new Path(otherArgs[0]));
            FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
    
            System.exit(job.waitForCompletion(true) ? 0 : 1);
        }
    }
    

     

    执行结果

     

     

    倒排索引 

    "倒排索引"是文档检索系统中最常用的数据结构,被广泛地应用于全文搜索引擎。它主要是用来存储某个单词(或词组)在一个文档或一组文档中的存储位置的映射,即提供了一种根据内容来查找文档的方式。由于不是根据文档来确定文档所包含的内容,而是进行相反的操作,因而称为倒排索引(Inverted Index)。

    实现"倒排索引"主要关注的信息为:单词、文档URL及词频。

     

    任务描述

    现有3张信息数据表,分别为商品库表goods3,商品访问情况表goods_visit3,订单明细表order_items3,goods表记录了商品的状态数据,goods_visit3记录了商品的点击情况,order_items3记录了用户购买的商品的信息数据,它们的表结构及内容如下:

    goods3(goods_id,goods_status,cat_id,goods_score)

    商品ID 商品状态 分类ID 评分
    1024600	6	52006	0
    1024593	1	52121	0
    1024592	1	52121	0
    1024590	1	52119	0
    1024589	1	52119	0
    1024588	1	52030	0
    1024587	1	52021	0
    1024586	1	52029	0
    1024585	1	52014	0
    1024584	1	52029	0

    goods_visit3(goods_id,click_num)

    商品ID 商品点击次数
    1024600	2
    1024593	0
    1024592	0
    1024590	0
    1024589	0
    1024588	0
    1024587	0
    1024586	0
    1024585	0
    1024584	0

    order_items3(item_id,order_id,goods_id,goods_number,shop_price,goods_price,goods_amount)

    明细ID 订单ID 商品ID 购买数据 商品销售价格 商品最终单价 商品金额
    251688	52107	1024600	1	31.6	31.6	15.8
    252165	52209	1024600	1	31.6	31.6	15.8
    251870	52146	1024481	1	15.6	15.6	7.8
    251935	52158	1024481	1	15.6	15.6	7.8
    252415	52264	1024480	1	69.0	69.0	69.0
    250983	51937	1024480	1	69.0	69.0	69.0
    252609	52299	1024480	1	69.0	69.0	69.0
    251689	52107	1024440	1	31.6	31.6	15.8
    239369	49183	1024256	1	759.0	759.0	759.0
    249222	51513	1024140	1	198.0	198.0	198.0

    要求查询goods_id相同的商品都在哪几张表中,并统计出现了多少次。

     

    设计思路

    (1)Map过程

    首先使用默认的TextInputFormat类对输入文件进行处理,得到文本中每行的偏移量及其内容。显然,Map过程首先必须分析输入的<key,value>对,得到倒排索引中需要的三个信息:单词、文档URL和词频,接着我们对读入的数据利用Map操作进行预处理。如下图所示:

    这里存在两个问题:

    第一,<key,value>对只能有两个值,在不使用Hadoop自定义数据类型的情况下,需要根据情况将其中两个值合并成一个值,作为key或value值。

    第二,通过一个Reduce过程无法同时完成词频统计和生成文档列表,所以必须增加一个Combine过程完成词频统计。

    这里将商品ID和URL组成key值(如"1024600:goods3"),将词频(商品ID出现次数)作为value,这样做的好处是可以利用MapReduce框架自带的Map端排序,将同一文档的相同单词的词频组成列表,传递给Combine过程,实现类似于WordCount的功能。

    (2)Combine过程

    经过map方法处理后,Combine过程将key值相同的value值累加,得到一个单词在文档中的词频,如下图所示。如果直接将下图所示的输出作为Reduce过程的输入,在Shuffle过程时将面临一个问题:所有具有相同单词的记录(由单词、URL和词频组成)应该交由同一个Reducer处理,但当前的key值无法保证这一点,所以必须修改key值和value值。这次将单词(商品ID)作为key值,URL和词频组成value值(如"goods3:1")。这样做的好处是可以利用MapReduce框架默认的HashPartitioner类完成Shuffle过程,将相同单词的所有记录发送给同一个Reducer进行处理。如下图所示:

    (3)Reduce过程

    经过上述两个过程后,Reduce过程只需将相同key值的所有value值组合成倒排索引文件所需的格式即可,剩下的事情就可以直接交给MapReduce框架进行处理了。如下图所示:

     

    代码

    package MapReduce.sort;
    import java.io.IOException;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.*;
    import org.apache.hadoop.mapreduce.lib.input.*;
    import org.apache.hadoop.mapreduce.lib.output.*;
    
    // 倒排索引
    //goods3(goods_id,goods_status,cat_id,goods_score)
    //goods_visit3(goods_id,click_num)
    //order_items3(item_id,order_id,goods_id,goods_number,shop_price,goods_price,goods_amount)
    //查询goods_id相同的商品都在哪几张表,并统计出现了多少次
    public class InvertedIndex {
    
        public static class doMapper extends Mapper<Object, Text, Text, Text>{
            public static Text myKey = new Text();   // 存储单词和URL组合
            public static Text myValue = new Text();  // 存储词频
            //private FileSplit filePath;     // 存储Split对象
            @Override
            protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
                String filePath=((FileSplit)context.getInputSplit()).getPath().toString();
                System.out.println("filePath= "+filePath);
                System.out.println("传给map的key为 "+key);//偏移量
                System.out.println("传给map的value为 "+value);//文件每行内容
                // Map过程必须分析输入的<key,value>对,得到倒排索引中需要的三个信息:单词、文档URL和词频
                String val[]=value.toString().split("\t");
                if(filePath.contains("goods")){
                    int splitIndex =filePath.indexOf("goods");
                    myKey.set(val[0] + ":" + filePath.substring(splitIndex));
                }else if(filePath.contains("order")){
                    int splitIndex =filePath.indexOf("order");//获取字符串中含有order的起始索引位置
                    //order表中的goods_id位于第三列,即val[2]
                    //以“goods_id:文件名”格式组成key
                    myKey.set(val[2] + ":" + filePath.substring(splitIndex));//获取字符串中指定索引位置开始的子串
                }
                myValue.set("1");
                context.write(myKey, myValue);
                System.out.println("map的key为 "+myKey.toString());
                System.out.println("map的value为 "+myValue.toString());
            }
        }
        // 这里存在两个问题:
        // 第一,<key,value>对只能有两个值,在不使用Hadoop自定义数据类型的情况下,需要根据情况将其中两个值合并成一个值,作为key或value值
        // 第二,通过一个Reduce过程无法同时完成词频统计和生成文档列表,所以必须增加一个Combine过程完成词频统计
    
    
        public static class doCombiner extends Reducer<Text, Text, Text, Text>{
            public static Text myKey = new Text();
            public static Text myValue = new Text();
            @Override
            protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
                //传给combine的key为map中set的myKey,如“1024140:order_items3”
                System.out.println("传给combine的key为 "+key);
                //key可能重复,一个key对应多个value,这些value组成了一个Iterable<Text> values的list,list中每个值都为1
                int sum = 0 ;
                for (Text value : values)
                    sum += Integer.parseInt(value.toString());//将key值相同的value值累加,得到一个单词在文档中的词频
    
                //分隔map传来的key(goods_id:文件名)
                int mysplit = key.toString().indexOf(":");
                myKey.set(key.toString().substring(0, mysplit));//goods_id
                myValue.set(key.toString().substring(mysplit + 1) + ":" + sum);//文件名:词频
                context.write(myKey, myValue);
                System.out.println("combiner key "+myKey.toString());
                System.out.println("combiner value "+myValue.toString());
            }
        }
        // 如果直接将输出作为Reduce过程的输入,在Shuffle过程时将面临一个问题:
        // 所有具有相同单词的记录(由单词、URL和词频组成)应该交由同一个Reducer处理,但当前的key值无法保证这一点,所以必须修改key值和value值
        // 这次将单词(goods_id)作为key值,URL和词频组成value值
        // 这样做的好处是可以利用MapReduce框架默认的HashPartitioner类完成Shuffle过程,将相同单词的所有记录发送给同一个Reducer进行处理
    
    
        public static class doReducer extends Reducer<Text, Text, Text, Text>{
            public static Text myKey = new Text();
            public static Text myValue = new Text();
            @Override
            //经过上述两个过程后,Reduce过程只需将相同key值的value值组合成倒排索引文件所需的格式即可,剩下的事情就可以直接交给MapReduce框架进行处理了。
            protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
                System.out.println("传给reduce的key为 "+key);
                System.out.println("传给reduce的values为 "+values);
                String myList = new String();
                for (Text value : values)
                    myList += value.toString() + ";";
                myKey.set(key);
                myValue.set(myList);
                context.write(myKey, myValue);
                System.out.println("reduce key "+myKey.toString());
                System.out.println("reduce value "+myValue.toString());
            }
        }
    
        public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
            Job job = Job.getInstance();
            job.setJobName("InversedIndex");
            job.setJarByClass(InvertedIndex.class);
    
            job.setMapperClass(doMapper.class);
            job.setCombinerClass(doCombiner.class);
            job.setReducerClass(doReducer.class);
    
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(Text.class);
    
            Path in1 = new Path("hdfs://localhost:9000/mr/in/goods3");
            Path in2 = new Path("hdfs://localhost:9000/mr/in/goods_visit3");
            Path in3 = new Path("hdfs://localhost:9000/mr/in/order_items3");
            Path out = new Path("hdfs://localhost:9000/mr/out/invertedindex");
    
            // 使用默认的TextInputFormat类对输入文件进行处理,得到文本中每行的偏移量及其内容,移交给Map
            FileInputFormat.addInputPath(job, in1);
            FileInputFormat.addInputPath(job, in2);
            FileInputFormat.addInputPath(job, in3);
            FileOutputFormat.setOutputPath(job, out);
    
            System.exit(job.waitForCompletion(true) ? 0 : 1);
        }
    }
    
    

     

    执行过程

    上述代码的执行过程为:
    1. 一个path作为filePath传给map,path中的文件的行偏移量作为传给map的key,path中文件的每行内容作为传给map的value
    2. 以'\t'split value,存储到val[]中
    3. 截取path中的文件名
    4. 根据path判断传给map的是具体哪个文件,根据文件名选择goods_id所在val[]列,设置key为goods_id:文件名,value为1,传给combine
    5. 重复1-4步,直到该文件读取完毕
    6. combine获取map传来的key和values list(key可能重复,一个key对应多个value,这些value组成了一个Iterable<Text> values的list,list中每个值都为1)
    7. 对每个key进行词频统计,遍历values累加其value值,赋给sum
    8. split map传来的key,获取goods_id和文件名
    9. 设置key为goods_id,value为“文件名:sum(词频)”
    10. 重复6-9步,直至map传来的全部combine完毕
    11. 重复1-10步,直至所有文件都combine完毕,将combian的key,value传给reduce
    12. 根据combine传来的key,遍历其values,以分号间隔集成一个String,设置成reduce的value,key不变
    13. 重复12步,直至combine传来的全部reduce完毕
    14. 将结果写入out文件

     

    执行结果

     

    展开全文
  •  src="{dede:field name='phpurl'/}/count.php?view=yes&aid={dede:field name='id'/}&mid={dede:field name='mid'/}" type='text/javascript' language="javascript">   动态(一般文章页用) 20.给近...

    收集自己觉得好的资料




    //织梦的网站查询手册

    //红色为问题集  //橄榄色为注释  //紫色为拓展


    1.网站标题(优化): 

    {dede:field.title/}_{dede:global.cfg_webname/}

    2.当前名称:

    {dede:field name='typename'/}

    3.导航条(父类、子类):

    {dede:channel type='top' row='8' currentstyle="<li><a href='~typelink~' class='thisclass'>~typename~</a> </li>"}

     <li><a href='[field:typelink/]'>[field:typename/]</a> </li>

    {/dede:channel}

    4.面包屑:

    {dede:field name='position'/}     //出来的效果是:首页 > 新闻动态 >

    {dede:field name='position' runphp='yes'}

    @me=substr(@me,0,-2);

    {/dede:field}                     //出来的效果是:首页 > 新闻动态 

    生成的代码为 <a href="#">首页</a> > <a href="#">新闻动态</a>

    函数的位置 include/typelink.class.php  

    参考网站:http://www.simple-studio.net/2011060216.shtml

    注意:在列表页的时候 {dede:field name='position'/} 效果是 首页 > 联系我们 >

          在封面页的时候 {dede:field name='positon'/} 效果是 首页 > 联系我们

          少一个后边的 > 

    删除当前位置下的超链接,只保留文字..

    方法1:

    文件\include\arc.archives.class.php

    文件\include\arc.listview.class.php 

    文件\include\arc.partview.class.php

    把三个文件里面的这句

    Fields['position'] = $this->TypeLink->GetPositionLink(true);

    都改成

    Fields['position'] = $this->TypeLink->GetPositionLink(false);

    方法2:

    {dede:field name='position' function="strip_tags(@me)"/}

    或者{dede:field name='position' function="html2txt(@me)"/}

    参考网站:http://www.cnblogs.com/Byrd/archive/2011/04/27/2030458.html

    5.关于列表页和内容页的分页代码和css样式(可以直接拿来使用)

    ul.pagesize{width:620px; margin:20px auto 10px; text-align:center; padding-bottom:10px;}

    ul.pagesize a{padding:5px; margin-right:5px; color:#333333; text-decoration:none;}

    ul.pagesize span.thisclass{padding:5px; margin-right:5px; color:#fc0;}

    ul.pagesize span.pageinfo{}

    列表页的php页面:include/arc.listview.class.php  分页代码

    文章页的php页面:include/arc.archives.class.php  分页代码

    也可以用文件夹下的各种酷炫分页效果。

    6.控制标签的字数(如description或者info或者body)

    [field:description function='cn_substr(@me,80)'/]

    [field:body function='cn_substr(@me,80)'/]

    不足显示全文,超过显示省略号...

    [field:title function='(strlen("@me")>26 ? cn_substr("@me",26)."…":"@me")'/]

    7.调用时间函数(多用于新闻列表的时间)

    [field:pubdate function="MyDate('Y-m-d H:i',@me)"/]

    pubdate 更新时间(发布时间)--可以修改

    senddate 出版时间--不可更改

    8.替换<div></div>等html标签的用法

    {dede:field.body runphp="yes"}

    $a=str_replace('div','p','@me');

    $b=str_replace('<br />','',$a);

    @me=str_replace(' ','',$b);

    {/dede:field.body}

    9.自定义表单增加时间的方法

    后台显示:

    ①.修改dede/templets/diy_list.htm,42行        

    else后面加入

    if($fielddata[1]=='datetime')
    {

       $fields[$field] = GetDateTimeMk($fields[$field]);

    前台显示:

    ②.templets/plus/list_diyform.htm 在以下位置添加上面的代码

    其它附件</a>";

    }

    --------------------》》在这个的后面添加以下代码。保存就OK

    if($fielddata[1]=='datetime')

    {

    $fields[$field] = GetDateTimeMk($fields[$field]);

    } 

    写在静态页面:

    <tr style="display:none;">

      <td align="right" valign="top">提交时间:</td>

      <td><input name="txtshowtime"  type="text" id="txtshowtime" style="width:250px" class="intxt"  /><script type="text/javascript">

    function chandeTime(){

    var date = new Date();

         var year = date.getFullYear();

         var month = date.getMonth()+1;    //js从0开始取 

         var date1 = date.getDate(); 

    document.getElementById("txtShowTime").value=year+"-"+month+"-"+date1+" "+date.toLocaleTimeString() ;

    window.setTimeout("chandeTime();",1000);

    }

    window.onload = chandeTime();

    </script></td>

    </tr>

    10.织梦的后台添加菜单选项卡

    dede/templets/index_menu2.htm

    加入一个选项卡,我放在了141行,在那个if判断权限的条件外,这样可以让编辑人员看到

    <a id='link9' class='mm'><div onClick="ShowMainMenu(9)">其他</div></a>

    这里注意你的id,link9不要和上边的id重复,然后 后边的js方法ShowMainMenu中也要传入9,是对应的,

    然后是下一步,还是这个页面,大概下边找到一些空的div,都是些id是ct加数字的,加上:

    <div id='ct9'></div> 

    这里ct后边的数字对应你上边的数字

    接下来找到 dede/inc/inc_menu.php 打开在最下边的一串---符号上边,加上

    <m:top item='9_' name='资讯其他管理' notshowall='1'  display='none' rank='sys_MakeHtml'>

      <m:item name='管理身份证' link='/plus/mood/mood_write_admin.php' rank='sys_MakeHtml' target='main' />

    </m:top>

    就可以在后台的 “其他”->“管理身份证” 中访问到你新加的功能了

    11.把数据保存到数据库主表 `#@__archives` 时出错,请把相关信息提交给DedeCms官方(解决方法)

    登陆系统后台–系统–SQL命令行工具,运行下面代码

    Alter TABLE `dede_archives` ADD COLUMN `voteid` int(10) NOT NULL DEFAULT 0 AFTER `mtype`;

    运行后更新下缓冲,重新发布文章,成功解决了。

    12.关于js文件由于编码的不同(gb2312或者utf-8)导致特效不出来的解决方案。

    把JS文件重新粘贴到新建好的JS文档里就OK啦

    13.一键更新四国语言版本的织梦问题。

    中文(不用)

    英文En(列表下选择En-index.htm模板)

    韩文Korean(列表下选择H-index.htm模板)

    一键更新就自动生成 index.html了。

    14.dedecms5.7 版后台编辑器无法显示问题。

    在系统设置里.Html编辑器选项(目前仅支持fck): fck 

    Html编辑器选项(目前仅支持fck): ckeditor 

    15.织梦DedeCms限制文章页上一篇、下一篇文章标题字数。给他们增加链接(直接用archives.class.php)

    编辑打开include/arc.archives.class.php文件

    查找:$this->PreNext['pre'] = "上一篇:{$preRow['title']} ";

    在这一行上面加上以下代码

    $preRow['title']=cn_substr($preRow['title'],30);//最多显示15个汉字

    查找:$this->PreNext['next'] = "下一篇:{$nextRow['title']} ";

    在这一行上面加上以下代码

    $nextRow['title']=cn_substr($nextRow['title'],30);//最多显示15个汉字

    然后再重新生成所有页面即可。

    参考网址:http://www.dedeadmin.com/?p=902

    修改织梦文档标题长度限制 

    1、进入后台--系统--系统设置--系统基本参数--其他选项--文档标题最大程度改为你要的长度原默认是60(这里改为了200)

    2、登陆数据库,改数据库表dede_archives表里面的title字段,原默认是60,(这里改为200).

    16.织梦一个字数代表几个字节。

    ①GBK        一个汉字两个字节

    ②utf-8      [3×(汉字数-2]+1 —— [3×(汉字数-2]+1+2

    17.修改织梦列表、文章默认的命名规则。

    I。①文章命名:(修改完添加栏目就能看见。批量修改

    include/common.inc.php

    //文档的默认命名规则 

    $art_shortname = $cfg_df_ext = '.html'; 

    $cfg_df_namerule = '{typedir}/{Y}/{M}{D}/{aid}'.$cfg_df_ext; 

    修改成 $cfg_df_namerule = 'posts/{aid}'.$cfg_df_ext; 

    ②列表命名:

    dede/templets/catalog_add.htm

    {typedir}/list_{tid}_{page}修改成自己需要的即可

    II。直接修改高级选项里边的文章命名规则单独修改

    III。系统-系统基本参数-其它选项-是否允许用目录作为文档文件名(文档命名规则需改为:{typedir}/{aid}/index.html)点是。然后把栏目文章命名规则改为{typedir}/{aid}/index.html  生成的文章目录为:例 http://127.0.0.2/ceshi/135/

    参考(http://www.zuimoban.com/php/cms/1155.html)

    http://hi.baidu.com/eatpeach/blog/item/5b353f4ee3efb5c6d0c86a58.html

    18.底层模板的修改在 include/typelink.class.php

    $typelink = "<a href='".$typepage."' title='查看 ".$typeinfos['typename']." 的全部文章'>".$typeinfos['typename']."</a>";

    19.关于文章页点击次数的两种调用。

    ①.{dede:field.click/}        静态(一般列表页用)

    ②.<script src="{dede:field name='phpurl'/}/count.php?view=yes&aid={dede:field name='id'/}&mid={dede:field name='mid'/}" type='text/javascript' language="javascript"></script>次       动态(一般文章页用)

    20.给近三天(或当天)发布的文章标题显示红色或加上new字或new小图片等。

    <li><span>[[field:pubdate function="MyDate('Y-m-d H:i:s',@me)"/]]</span> <a href="[field:arcurl/]">

    [field:pubdate runphp='yes'] 

    $ntime = time();

    $oneday = 3600 * 24;

    if(($ntime - @me)<$oneday) @me = "<font color='#900'>";

    else @me = "";

    [/field:pubdate]

    [field:title/]

    [field:pubdate runphp='yes'] 

    $ntime = time();

    $oneday = 3600 * 24;

    if(($ntime - @me)<$oneday) @me = "new!</font>";

    else @me = "";

    [/field:pubdate]

    </a></li>

    给近三天(或当天)发布的文章显示红色日期或加上new字或new小图片等

    1、==========红色的日期========

    [field:pubdate runphp='yes'] 

    $a="<font color=red>".strftime('%m-%d',@me)."</font>";

    $b=strftime('%m-%d',@me);

    $ntime = time(); 

    $day3 = 3600 * 24 * 3;

    if(($ntime - @me) < $day3) @me = $a;

    else @me =$b; 

    [/field:pubdate]

    2、==========红色的(new)========

    [field:pubdate runphp='yes']

    $aa=strftime('%m-%d',@me);

    $ntime = time();

    $tagtime = @me;

    $day3 = 3600 * 24 * 3;

    if($tagtime > $ntime-$day3) @me = "<font color='red'>(new)</font>";

    else @me = $aa;

    [/field:pubdate]

    3、==========加new.gif小图片========

    [field:pubdate runphp='yes']

    $aa=strftime('%m-%d',@me);

    $ntime = time();

    $tagtime = @me;

    $day3 = 3600 * 24 * 3;

    if($tagtime > $ntime-$day3) @me = "<img src='new.gif' />".$aa;

    else @me = $aa;

    [/field:pubdate]

    注意 ①:当天的去除*3     ②:img src='new.gif' /中不能用双引号,否则不行 

    ===================================

    [field:pubdate runphp="yes"] 

    if((time()-@me)<(60*60*24)){@me=' <font color="#ff6600">'.strftime("%H:%M",@me).'</FONT>';} 

    else {@me=strftime("%m-%d",@me);}           

    [/field:pubdate]

    21.dedecms5.7修改文章内容的同时不修改发表日期时间。

    /dede/templets/article_edit.htm

    365行左右把

    $nowtime = GetDateTimeMk(time());

    改成

    $nowtime = GetDateTimeMk($arcRow["pubdate"]);

    关于织梦将文章审核时间与发布日期同步的修改方法

    http://blog.sina.com.cn/s/blog_80a856e50100vudp.html

    22.织梦后台 栏目内容里边的列表 的更新时间 按照修改的来(DEDE后台文章排序按文章发布时间)  

    修改

    /dede/content_list.php  文件

    查找

    $orderby = empty($orderby) ? ‘id’ : eregi_replace("[^a-z0-9]", "", $orderby);

    修改为

    $orderby = empty($orderby) ? ‘pubdate’ : eregi_replace("[^a-z0-9]", "", $orderby);

    到后台模版目录下  修改 /dede/content_list.htm  文件

    查找

    <td>{dede:field.senddate function=’GetDateMk(@me)’/}</td>

    修改为

    <td>{dede:field.pubdate function=’GetDateMk(@me)’/}</td>

    23.infolen简介控制字数没有效果的解决方法(description等同于infos)

    在列表页 description=infos 在文章页 只用description不用infos

    Ⅰ.字数变少

    ①.底层标签[field:description/] 改成[field:infos/]

    ②.[field:description function='cn_substr(@me,66)'/]

    Ⅱ.字数变多

    ①修改 系统--系统基本参数--其它选项 里的自动摘要长度 如改为 600

    ②修改 数据表 dede_archives下的 description的结构 把varchar(250)改成varchar(600)

    ③修改 dede/article.edit.php 

    第113行 $description = cn_substrR($description,250);

    修改为  $description = cn_substrR($description,600);或者$description = $description;

    24.织梦留言板的研究

    ①通过自定义表单(可在前后台查看,缺点是管理员不能回复)

    dedecms自定义表单模板:

    templets/plus/view_diyform.htm内容模板

    templets/plus/post_diyform.htm发布模板

    templets/plus/list_diyform.htm 列表模板

    1. 建个自定义表单 

    2. 点击 前台预览 -- 发布信息

    3. 查看源码 找到<form 开始 及 </form>之间的代码 复制下来

    4. 这里我们测试 把他放到首页的模版里:

       放在{dede:include filename="head.htm"/}(仅测试玩)

    参考链接:http://dedecms8.blog.163.com/blog/static/167685605201051251927196/

    拓展:

    目前所做的留言一般用自定义表单.

    如(科瑞达:http://www.colouroad.com/kefu/3/;威达龙:http://www.weidalong.com/tsjy/;三夏:http://samsummercom.host.tedaweb.com/China/contact/2/;新宇酒店:http://xysdjdcom.host.tedaweb.com/a/lxwm/2/;)

    在后台选项卡中添加 留言菜单 (详见问题10)可直接调用文件下的 index_menu2.htm和 inc_menu.php

     

    ②通过织梦自带的留言簿模块(可查看,也可回复)

    先安装留言簿模块。/plus/guestbook.php 模板 /templets/plus/guestbook.htm 自己修改模板就行.

    或者手写一个模板 form 提交的时候 到 /plus/guestbook.php 类似guestbook.htm 格式来.

    ③插件评论啦 微博、QQ、人人直接评论 能用Q登陆发布的留言(互联网那点事)

    http://pinglun.la/ 在其注册一个号   账号:qiwen5de@126.com   密码:111111

    插入类似这种代码:

    <!-- PingLun.La Begin -->

    <div id="pinglunla_here"></div><a href="http://pinglun.la/" id="logo-pinglunla"></a><script type="text/javascript" src="http://pinglun.la/64f1072ea891893f199aabf132c248c53e9a640a.js" charset="utf-8"></script>

    <!-- PingLun.La End -->

    ④织梦自带的评论

    见文件夹下的ajax.htm放在默认的模板下

    ajaxfeed.css放在\templets\default\style下

    调用评论插件:{dede:include file='ajaxfeedback.htm' /}

    feedback

    功能说明:用于调用最新评论

    {dede:feedback}

    <ul>

    <li class='fbtitle'>[field:username function="(@me=='guest' ? '游客' : @me)"/] 对 [field:title/] 的评论:</li>

    <li class='fbmsg'> <a href="plus/feedback.php?aid=[field:aid/]" class='fbmsg'>[field:msg /]</a></li>

    </ul>

    {/dede:feedback}

    织梦首页

    {dede:feedback row='5' titlelen='24' infolen='80'}

          <li> <small><a href="#" class="username">[field:username function="(@me=='guest' ? '游客' : @me)"/]</a> 评论 <a href="[field:global.cfg_phpurl/]/feedback.php?aid=[field:aid/]" class="title">[field:title/]</a></small>

           <p>[field:msg/]</p>

          </li>

    {/dede:feedback}

    25.给自定义表单添加验证码

    ①.首先找到 /plus/diy.php

    在头部引入文件

    require_once(DEDEINC.'/membermodel.cls.php');

    然后找到

    elseif($do == 2)

    {

    这里,加入验证代码

    //验证码验证

    $svali = GetCkVdValue();

       if(preg_match("/1/",$safe_gdopen)){

           if(strtolower($vdcode)!=$svali || $svali=='')

             {

               ResetVdValue();

               ShowMsg('验证码错误!', '-1');

               exit();

              }           

    }

    ②.在你要引入自由表单的模板页面中加入验证码

    <input type="text" class="intxt w200" style="width: 50px; text-transform: uppercase;" id="vdcode" name="vdcode"/>

    <img id="vdimgck" align="absmiddle" οnclick="this.src=this.src+'?'" style="cursor: pointer;" alt="看不清?点击更换" src="/include/vdimgck.php"/> 看不清? <a href="javascript:void(0)" οnclick="changeAuthCode();">点击更换</a>

    关于自定义表单怎么在模板页中使用,自定义表单怎么验证,就不再说了

    设置自定义表单中的字段为必填项

    ①.php验证

    在plus/diy.php的第40行下加

    //增加必填字段判断

    if($required!=''){

    if(preg_match('/,/', $required))

        {

            $requireds = explode(',',$required);

            foreach($requireds as $field){

                if($$field==''){

                    showMsg('带*号的为必填内容,请正确填写', '-1');

                    exit();

                }

            }

        }else{

            if($required==''){

                showMsg('带*号的为必填内容,请正确填写', '-1');

                exit();

            }

        }

    }

    //end

    ②.在模板的表单增加

    <input type="hidden" name="required" value="name,qq" />

    参考网站:http://www.dedecms8.com/dedecms/2845.html

    总结自定义表单(发布留言验证码,发布日期,验证必填项) 9 24 25

    26.用field调用站点根网址  插件 评论啦使用

    ① {dede:global.cfg_basehost/}                     127.0.0.1

    ② [field:global name='cfg_webname'/]              127.0.0.1

    例:http://www.alibuybuy.com/category/collection

    列表页:

    {dede:list}

    <script type="text/javascript">document.write('<script type="text/javascript" src="http://pinglun.la/64f1072ea891893f199aabf132c248c53e9a640a/cc.js?t=%EF%BC%88%7Bcount%7D%E4%B8%AA%EF%BC%89&o=1&p='+encodeURIComponent("[field:global name='cfg_basehost'/][field:arcurl/]")+'" charset="utf-8"></'+'script>')</script>

    {/dede:list}

    文章页:

    <script type="text/javascript">document.write('<script type="text/javascript" src="http://pinglun.la/64f1072ea891893f199aabf132c248c53e9a640a/cc.js?t=%EF%BC%88%7Bcount%7D%E6%9D%A1%EF%BC%89&o=1&p='+encodeURIComponent("{dede:global.cfg_basehost/}{dede:field.arcurl/}")+'" charset="utf-8"></'+'script>')</script>

    27.安装织梦的时候 GD库不支持

    GD是php的图片扩展,是用来操作图片的,平时用的验证码,图片上打水印都得gd库支持

    修改dede/login.php和dede/templets/login.htm 判断后台验证码

    login.php 

    67行 if{ 下边注释掉

    /*ResetVdValue();

            ShowMsg('验证码不正确!','login.php',0,1000);

            exit;

        } else {*/

    login.htm 27行  注释掉

    <!--<?php

    if(preg_match("/6/",$safe_gdopen))

    {

    ?>

    <dt>验证码:</dt>

    <dd><input id="vdcode" type="text" name="validate" style="text-transform:uppercase;"/><img id="vdimgck" align="absmiddle" onClick="this.src=this.src+'?'" style="cursor: pointer;" alt="看不清?点击更换" src="../include/vdimgck.php"/>

    <a href="#" onClick="changeAuthCode();">看不清? </a></dd>

    <?php

    }

    ?>-->

    28.织梦列表页(自定义模型,附加表字段) 

    列表页:

    {dede:list pagesize='3'}

    [field:xinxi/]

    [field:xm/]

    {/dede:list}

    织梦的内容页:可以直接使用 {dede:field.xinxi/}与{dede:field.xm/}

    文章页:用arclist调用于附加表字段的方法:

    要获取附加表内容,必须符合两个条件

    1、指定 channelid 属性

    2、指定要获得的字段 addfields='字段1,字段'

    如:

    {dede:arclist addfields='filetype,language,softtype' row='8' channelid='3'}

    [field:textlink /] - [field:softtype /]<br />

    {/dede:arclist}

    29.织梦的首页、封面页arclist分页标签示例 参考网址(http://bbs.dedecms.com/258534.html)

    ①首先必须在首页的</head>前面加上:

    <script language="javascript" type="text/javascript" src="{dede:global.cfg_cmsurl/}/include/dedeajax2.js"></script>

    ②必须引入以下javascript代码:

    <script> 

    function multi(pagenum,tagid) 

    var taget_obj = document.getElementById(tagid); 

    var taget_obj_page = document.getElementById("page_"+tagid); 

    myajax = new DedeAjax(taget_obj,false,false,'','',''); 

    myajax.SendGet2("/plus/arcmulti.php?mtype=0&pnum="+pagenum+'&tagid='+tagid); 

    myajax = new DedeAjax(taget_obj_page,false,false,'','',''); 

    myajax.SendGet2("/plus/arcmulti.php?mtype=1&pnum="+pagenum+'&tagid='+tagid); 

    DedeXHTTP = null; 

    </script>

    ③在arclist标签中必须含有tagid与pagesize参数。 第一个是缓存名,第二个是单页条数;例如:

    {dede:arclist tagid='index' pagesize='5'} 

    <li><b><a href="[field:arcurl/]" style="color: #FF6633">[field:title/]</a></b></li> 

    <p class="my_tj_info">[field:info/]...</p> 

    {/dede:arclist}

    ④必须存在arcpagelist标签,且必须声明缓存参数tagid且缓存参数与arclist中tagid保持一致。例如:

    {dede:arcpagelist tagid='index'/}

    现在贴上一个完整代码供大家测试参考:

    <script language="javascript" type="text/javascript" src="{dede:global.cfg_cmsurl/}/include/dedeajax2.js"></script> 

    <script> 

    function multi(pagenum,tagid) 

    var taget_obj = document.getElementById(tagid); 

    var taget_obj_page = document.getElementById("page_"+tagid); 

    myajax = new DedeAjax(taget_obj,false,false,'','',''); 

    myajax.SendGet2("/plus/arcmulti.php?mtype=0&pnum="+pagenum+'&tagid='+tagid); 

    myajax = new DedeAjax(taget_obj_page,false,false,'','',''); 

    myajax.SendGet2("/plus/arcmulti.php?mtype=1&pnum="+pagenum+'&tagid='+tagid); 

    DedeXHTTP = null; 

    </script> 

    {dede:arclist tagid='index' pagesize='5'} 

    <li><b><a href="[field:arcurl/]" style="color: #FF6633">[field:title/]</a></b></li> 

    <p class="my_tj_info">[field:info/]...</p> 

    {/dede:arclist} 

    {dede:arcpagelist tagid='index'/}

    30.织梦arclist 列表页调出的是 当前栏目下的文章。

    调用所有栏目下的文章,给arclist一个属性 typeid='top'

    31.织梦的tag标签(http://www.dedeadmin.com/?p=1501)        后台函数/include/taglib/tag.lib.php

    I.{dede:tag sort='new' getall='0'}

    <a href='[field:link/]'>[field:tag /]</a>                  //出来的效果不带数字  <a href='#'>seo</a>

    {/dede:tag}

    II.{dede:tag row='6' sort='new'/}                          //出来的效果带数字<a href='#'>1(1)</a>

    ①、选择你所要加页面的模板,一般是在首页index.htm   加上如下代码

    <!-- /下面开始tag标签云 -->

    <dl class="tbox light">

    <dt><strong>Tags标签云</strong></dt>

    <dd>{dede:tag row='45' getall='1' sort='hot'}

    <a href='[field:link/]' title="[field:tag /]([field:total /])" style="[field:total runphp=yes]@me=getTagStyle();[/field:total]">[field:tag /]</a> 

    {/dede:tag} 

    </dd>

    </dl>

    <!-- /tag标签云结束 -->

    ②、在/include/common.func.php 中加入如下函数。

    function getTagStyle()  

    {  

    $minFontSize=8; //最小字体大小,可根据需要自行更改  

    $maxFontSize=18; //最大字体大小,可根据需要自行更改  

    return 'font-size:'.($minFontSize+lcg_value()*(abs($maxFontSize-$minFontSize))).'px;color:#'.dechex(rand(0,255)).dechex(rand(0,196)).dechex(rand(0,255));  

    }

    tag标签静态化(插件)

    ①、在DEDE网站根目录,建立“tag”目录(小写)

    ②、在DEDE后台SQL运行器里,执行以下一条SQL:

    ALTER TABLE `#@__tagindex` ADD `maketime` INT( 10 ) UNSIGNED NOT NULL DEFAULT '0';

    ③、增加文件:

    templets/default/list_tag.htm //可从文章列表页复制修改

    templets/default/index_tag.htm //可从tag.htm复制

    dede/makehtml_tag_action_list.php

    dede/makehtml_tag_action_index.php

    dede/makehtml_tag.php

    dede/templets/makehtml_tag.htm

    include/arc.taghtml.class.php

    ④、替换文件:

    dede/inc/inc_menu.php

    include/taglib/tag.lib.php

    include/extend.func.php

    参考网址:http://www.willacat.com/2011/05/420.html

    32.织梦标题颜色

    在后台发文章的时候  高级参数-标题颜色 设置一个就ok了

    33.seo标题 给栏目设置seo标题、关键字、描述(http://www.dedecms8.com/dedecms/2835.html)

    内容页调用SEO标题:在<title></title>之间加进以下代码:

    {dede:field name='typeid' runphp='yes'} 

    $id=@me; 

    global $dsql; 

    $sql="select seotitle from dede_arctype where id=$id"; 

    $row=$dsql->getOne($sql); 

    @me=$row["seotitle"]; 

    {/dede:field}

     

    内容页调用栏目描述:

    把默认的<meta name="description" content="{dede:field.description function='html2text(@me)'/}" />改成:

    <meta name="description" content="{dede:field name='typeid' runphp='yes'} 

    $id=@me; 

    global $dsql; 

    $sql="select description from dede_arctype where id=$id"; 

    $row=$dsql->getOne($sql); 

    @me=$row["description"]; 

    {/dede:field}" /> 

    内容页调用栏目关键字:

    把默认的<meta name="keywords" content="{dede:field.keywords/}" /> 改成:

    <meta name="keywords" content="{dede:field name='typeid' runphp='yes'} 

    $id=@me; 

    global $dsql; 

    $sql="select keywords from dede_arctype where id=$id"; 

    $row=$dsql->getOne($sql); 

    @me=$row["keywords"]; 

    {/dede:field}" /> 

    首页:

    <meta name="keywords" content="{dede:global.cfg_keywords/}" />                                          //总体关键字

    <meta name="description" content="{dede:global.cfg_description/}" />                                    //总体描述

    栏目页(封面页、列表页)直接:

    <meta name="keywords" content="{dede:field name='keywords'/}" />                                        //栏目关键字

    <meta name="description" content="{dede:field name='description' function='html2text(@me)'/}" />        //栏目的描述

    文章页 

    <meta name="keywords" content="{dede:field name='keywords'/}" />                                        //文章的关键字

    <meta name="description" content="{dede:field name='description' function='html2text(@me)'/}" />        //文章的描述

    34.Dedecms系统登录、更新的提示信息修改方法

    include/common.func.php 里边有

    dedecms提示信息

    参考网址:http://www.dedecms8.com/dedecms/dedecms-fz/389.html

    35.织梦的自定义变量存在的数据表

    存在于dede_sysconfig

    36.用于首页调取公司简介。(部分)

    {dede:sql sql='SELECT * FROM `dede_arctype` WHERE `id` =8'}

    [field:content runphp='yes']

    @me = strip_tags(@me);                            //织梦剥离html函数

    @me=cn_substr(@me,420);                           //截取字符串函数

    [/field:content]......

    {/dede:sql}

    或者:[field:content function="Html2Text('@me')"/]

    给织梦DEDECMS5.7的编辑器添加中文字体选项方法

    (查找font_names)

    下面分享一下为ckeditor网页编辑器添加中文字体的方法:

    i.font_names='Arial/Arial, Helvetica, sans-serif;Comic Sans MS/Comic Sans MS, cursive;Courier New/Courier New, Courier, monospace;Georgia/Georgia, serif;Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;Tahoma/Tahoma, Geneva, sans-serif;Times New Roman/Times New Roman, Times, serif;Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;Verdana/Verdana, Geneva, sans-serif;宋体/宋体;黑体/黑体;仿宋/仿宋_GB2312;楷体/楷体_GB2312;隶书/隶书;幼圆/幼圆;微软雅黑/微软雅黑';

    需要特别注意的是:添加的字体,要写成诸如“宋体/宋体”的形式,而不是“宋体”。即“显示的字体名称/实际字体名称”的格式。

    参考网址:http://www.51dedecms.com/news/dedecms/2011/1030/3067.html

    37.织梦分页(不要页码,显示上一页 下一页)

    include/arc.listview.class.php的

    978行改为 

    else

    {

    $indexpage="<a>首页</a>\r\n";

    $prepage.="<a>上一页</a>\r\n";

    }
    990行改为

    else

    {

           $endpage="<a>末页</a>\r\n";

    $nextpage.="<a>下一页</a>\r\n";

    }

    前台调用 {dede:pagelist listitem="info,index,end,pre,next"/}

    38.让DedeCMS的索引默认从零开始的方法[field:global.autoindex/]

    这几天帮人做个简单的网站,用DedeCMS搭建,做到幻灯这块儿时,不想用官方提供的那个幻灯要是,自己做的话用到了DedeCMS的[field:global.autoindex/] 这个标签,但是却发现这个默认的索引时从1开始的,用起来不太方便,那么怎们能让默认索引从0开始呢?就要使用PHP语法解决,具体方法如下:

    [field:global name=autoindex runphp="yes"]@me=@me-1;[/field:global] 

    只要这样就可以简单解决DedeCMS默认索引从0开始的问题了。

    参考网址:http://www.vvschool.cn/html/web/cms/2010/1006/4442.html

    39.织梦的rss订阅(templets/plus/rss.htm)

    第一步,建立RSS文件,命名为rss.php,把此文件上传到网站根目录,rss.php代码如下:

    <?php

    require_once (dirname(__FILE__) . "/include/common.inc.php");

    require_once DEDEINC."/arc.partview.class.php";

    $pv = new PartView();

    $pv->SetTemplet($cfg_basedir . $cfg_templets_dir . "/default/rss.htm");

    header("Content-type:application/xml");

    $pv->Display();

    ?>

    第二步,建立RSS模板文件rss.htm,把此文件上传到模板目录下(\templets\default),rss.htm代码如下:

    <?xml version="1.0" encoding="gb2312" ?>

    <rss version="2.0">

    <channel>

    <title>{dede:global.cfg_webname/}</title>

    <link>{dede:global.cfg_basehost/}</link>

    <description>{dede:global.cfg_description/}</description>

    <language>zh-cn</language>

    <generator>{dede:global.cfg_webname/}</generator>

    <webmaster>{dede:global.cfg_adminemail/}</webmaster>

    {dede:arclist row='60' col='1' titlelen='100' orderby='pubdate'}

    <item>

    <link>http://www.lixiaojiang.com[field:arcurl/]</link>

    <title><![CDATA[[field:title function='html2text(@me)'/]]]></title>

    <author>[field:writer/]</author>

    <category>[field:typename/]</category>

    <pubDate>[field:pubdate function='strftime("%a, %d %b %Y %H:%M:%S +0800",@me)'/]</pubDate>

    <guid>http://www.lixiaojiang.com[field:arcurl/]</guid>

    <description><![CDATA[[field:description function='html2text(@me)'/] ... <br /><b>文章分类</b>:[field:typename/]<br /><a href="[field:arcurl/]" target="_blank">阅读全文</a> | <a href="[field:arcurl/]" target="_blank">评论回复</a>]]></description>

    </item>

    {/dede:arclist}

    </channel>

    </rss>

    第三步,在后台增加一个单页面,“模板文件名”项中输入第2步中涉及的模板文件rss.htm,早“文件名”中输入未来Rss订阅地址,这里我就直接生成在CMS根目录下了。

    参考网址:http://down.chinaz.com/try/201108/960_1.htm     (完整版)

              http://www.lixiaojiang.com/xj/it/2011/35.html  (未全)

    40.QQ的邮件订阅

    http://list.qq.com/           QQ邮件

    http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20015&&no=1000676

    http://www.feedsky.com/       feed添加、发布等等  feedsky

    41.用JS实现今天的日期

    <script language=JavaScript>

    today=new Date();

    function initArray(){

    this.length=initArray.arguments.length

    for(var i=0;i<this.length;i++)

    this[i+1]=initArray.arguments[i]  }

    var d=new initArray(

    "星期日",

    "星期一",

    "星期二",

    "星期三",

    "星期四",

    "星期五",

    "星期六");

    document.write(today.getYear(),"年",today.getMonth()+1,"月",today.getDate(),"日","  ",d[today.getDay()+1]);

    </script>

    42.一键批量删除织梦未审核的文档

    后台-系统-SQL命令行工具 运用命令行来解决这个问题

    delete from `dede_archives` where arcrank=-1;

    简单的一行代码就可以删除所有待审核的文档

    参考网址:http://www.82gp.com/dt/47.html

    43.织梦网站地图

    ①.普通网站地图          

    1.荣大汽车

    参考:http://www.rdgm.net/data/sitemap.html

    在需要的地方加上 {dede:global name='maplist'/}

    生成的代码是:

    <div class="linkbox">

    <h3><a href='/a/webbase/'>网页基础</a></h3>

    <ul class="f6">

    <li><a href='/a/webbase/html/'>HTML</a></li>

    <li><a href='/a/webbase/div-css/'>DIV&CSS</a></li>

    <li><a href='/a/webbase/javascript-ajax/'>Javascript/Ajax</a></li>

    <li><a href='/a/webbase/dreamweaver/'>Dreamweaver</a></li>

    </ul>

    </div>

    织梦DedeCMS网站地图优化技巧:生成根目录

    http://www.dedeadmin.com/?p=2707

    http://hi.baidu.com/yuhua2004/blog/item/034e782e798d03f18b139974.html

    2.船厂的普通地图

    单独写出来,写成一个静态页。http://www.shiprepair-xgsy.com/html/map/

    44.织梦的描述(有描述就显示内容,没有描述就不显示)

    {dede:field.description runphp='yes'}

    if(@me!='' )@me = '

    <div class="intro">'.@me.'</div>

     ';

    {/dede:field.description}

    {dede:field name='source' runphp='yes'}

    if(@me == "") @me = "";else @me = "来 源:".@me;

    {/dede:field} 

    {dede:field.description runphp='yes'}

      if(@me<>'' )@me = '

      <div class="jj">【导读】:'.@me.'</div>

      ';

    {/dede:field.description}

    45.织梦自带的评论(详见目录下的ajax.htm模板和ajaxfeed.css)

    引入css

    <link href="{dede:global.cfg_templets_skin/}/style/dedecms.css" rel="stylesheet" media="screen" type="text/css" />

    引入js

    <script language="javascript" type="text/javascript" src="{dede:global.cfg_cmsurl/}/include/dedeajax2.js"></script>

    引入调用代码

    {dede:include file='ajaxfeedback.htm' /}

    46.织梦的统计流量(51la或者cnzz)和QQ在线交谈可以通过广告代码调用。

    参考资料:http://han2000lei.iteye.com/blog/404732

    QQ在线交谈设置:http://wp.qq.com/index.html

    淘宝销售榜榜单:http://top.taobao.com/level2.php?cat=TR_JJ&from=&pid=mm_25225465_0_0&show=brand&stat_ref=tops_module&goodsFilter=all

    写入js广告引用iframe

    分享代码 用织梦广告引入

    47.织梦友情链接(后台\include\taglib\flink.lib.php)

    V53标记:{dede:flink row='24'/}

    type='image' 或textall,图片链接,text文字链接;

    row='24' 链接数量

    titlelen='24' 站点文字的长度

    linktype='2' 链接位置首页 linktype='1' 链接位置内页

    typeid='0' 所有类型,可以在系统后台[模块]-[友情链接]中的“网站类型管理”中查看 

    V57标记:flinktype  详细参考(http://blog.sina.com.cn/s/blog_917e0c4d0100yc7l.html) 

    ① DEDECMS默认代码:     {dede:flink row='24'/}                                                                     生成的有li,a

    ② 图片友情链接:        {dede:flink row='24' type='image' titlelen="24" typeid="0"} [field:link /] {/dede:flink}   生成的没有li的只有a

    ③ 文字友情链接:        {dede:flink row='24' type='text' titlelen="24" typeid="0"} [field:link /] {/dede:flink}    生成的没有li的只有a

    ④ 调用全部类型链接:    {dede:flinktype type="dedecms"}{dede:flink/}{/dede:flinktype}   [field:typename/]类型名称

    拓展: {dede:flink row='24' type='image' titlelen="24" typeid="0"} [field:link /] {/dede:flink} 生成的代码:<a href=''>seo</a>  

           {dede:flink row='24' type='image' titlelen="24" typeid="0"}<li>[field:link /]</li>{/dede:flink}生成的代码:<li><a href=''>seo</a></li>  

           {dede:flink type='text'}{/dede:flink}    生成的代码:<li><a href=''>seo</a></li>           

    修改实现织梦DedeCms下拉式友情链接 (http://www.dedeadmin.com/?p=567)          

    48.arclist调用有图片的文章

    ① flag='p'               有缩略图才显示  没有缩略图的不显示

    ② type='image.'          有缩略图才显示  没有缩略图的不显示

    调用

    ① [field:litpic/]       <img src="[field:litpic]" />

    ② [field:picname/]      <img src="[field:picname]" />  

    ③ [field:image/]        [field:image/]  对imgwidth='' imgheight='' 定义有效 ==<img src="" /> 

    默认的imgwidth和imgheight为120 (include/arc.listview.class.php)

    49.父栏目 封面模板、列表模板、文章模板选择之后 让N多子栏目和他有共同的模板。(栏目描述不会修改)

    点父栏目高级选项-继承选项 打钩 同时更改下级栏目的浏览权限、内容类型、模板风格、命名规则等通用属性 点确定 然后发现子栏目的模板都自动改了。

    50.[field:typelink/] 调用栏目分类

    textlink = <a href='arcurl'>title</a>

    typelink = <a href='typeurl'>typename</a>

    imglink = <a href='arcurl'><img src='picname' border='0' width='imgwidth' height='imgheight'></a>

    image = <img src='picname' border='0' width='imgwidth' height='imgheight' alt=’titile’>

    51.织梦模板下的栏目页 有图显示图,没图显示默认缩略图。修改为有图显示图,没图不显示

    官方:

    [field:array runphp='yes']

    @me = (empty(@me['litpic']) ? "" : "<a href='{@me['arcurl']}' class='preview'><img src='{@me['litpic']}'/></a>"); 

    [/field:array]

    修改后:

    [field:array runphp='yes']

    @me = (strpos(@me['litpic'],'defaultpic') ? "" : "<a href='{@me['arcurl']}' class='preview'><img src='{@me['litpic']}'/></a>"); [/field:array]

    参考网址:http://www.yzzmf.com/html/fangzhanjiqiao/dedejiqiao/2011-09-30/1937.html

    52.专题 缩略图(强制缩略图大小,对背景填充)

    一张图片在网站中不同尺寸的缩略图。

    ①。系统-附件设置,把缩略图默认宽度、默认高度设为大于等于你全站所有调用缩略图的最大尺寸

    ②。include/extend.func.php加入

    function thumb($imgurl, $width, $height, $bg = true)

    {

    global $cfg_mainsite,$cfg_multi_site;

    $thumb = eregi("http://",$imgurl)?str_replace($cfg_mainsite,'',$imgurl):$imgurl;

    list($thumbname,$extname) = explode('.',$thumb);

    $newthumb = $thumbname.'_'.$width.'_'.$height.'.'.$extname; 

    if(!$thumbname || !$extname || !file_exists(DEDEROOT.$thumb)) return $imgurl;

    if(!file_exists(DEDEROOT.$newthumb)) 

    {

    include_once DEDEINC.'/image.func.php';

    if($bg==true)

    {

    ImageResizeNew(DEDEROOT.$thumb, $width, $height, DEDEROOT.$newthumb);

    }

    else

    {

    ImageResize(DEDEROOT.$thumb, $width, $height, DEDEROOT.$newthumb);

    }

    }

    return $cfg_multi_site=='Y'?$cfg_mainsite.$newthumb:$newthumb;

    }

    调用方法:

    标签 : [field:picname function='thumb(@me,$width,$height,$bg)'/]

    参数说明:

    $width:缩略图宽度(整数)

    $height:缩略图高度(整数)

    $bg:是否用空白填补,默认自动填补,背景填充颜色在系统-附件设置里(true/false)

    举例: 

    调用长宽为100像素的缩略图:[field:picname function='thumb(@me,100,100)'/] 

    保留原有比例,不自动填充(不建议):[field:picname function='thumb(@me,100,100,false)'/]

    等比例缩放,空白部分背景填充

    参考网址:http://bbs.dedecms.com/275267.html

    53.复制网页内容时自动加入版权内容代码

    <script type=”text/javascript”>

    document.body.oncopy = function () { setTimeout( function () { var text =clipboardData.getData(“text”); if (text) { text = text + “\r\n转自:织梦管理员之家[http://www.dedeadmin.com] \r\n原文链接:”+location.href; clipboardData.setData(“text”,text); } }, 100 ) }

    </script>

    参考网址:http://www.dedeadmin.com/?p=357

    织梦统计代码
    共有会员:您是第N位客人。http://www.dedeadmin.com/?p=274

    54.调用人气、评论数

    人气(点击数):<script src="{dede:field name='phpurl'/}/count.php?view=yes&aid={dede:field name='id'/}&mid={dede:field name='mid'/}" type='text/javascript' language="javascript"></script>

    评论数:{dede:field.id runphp='yes'}$dsql = new dedesql(false);$dsql -> SetQuery("Select count(id) as c from #@__feedback where aid=".@me);$row = $dsql -> getone();@me=$row['c'];{/dede:field.id}

    [field:scores/]    评论数

    我要评论 跳转到评论框 

    <a  id="commentbeginid" class="icon_repost" οnclick="gIsFocus = true; scrollTo(0, findPosY(O('post_inner_id'))) ;  setTimeout('document.getElementById(\'commentText\').focus()',120);   return false;" ></a>

    55.数据库被垃圾信息发布 所要处理的表

    #@__member    member_company   member_flink   member_person  member_space  member_tj  tagindex  taglist

    uploads  arctiny archives addonarticle

    56.DedeCms系统未审核投稿禁止动态浏览(收录)解决方案

    dedecms用户投稿即使未审核,也是可以动态浏览的(/plus/view.php?aid=***)

    编辑打开/plus/view.php文件(注:这个文件是文档的动态浏览文件),找到如下代码:

    //检查阅读权限  

    $needMoney = $arc->Fields['money'];   $needRank = $arc->Fields['arcrank'];  

    在下面一行加入以下代码:

    $mid = $arc->Fields['mid'];  

    if(($cfg_ml->M_Rank < 1 || $mid <> $cfg_ml->M_ID) && $needRank == -1){       showMsg("你无查看权限",-1);  

        exit();   }  

    保存关闭即可。

    参考网址:http://www.bbscms.net/html/website/seo/20110910/4446.html

    57.导航页面(用图片做)

    <ul>

            <li><a href="{dede:global.cfg_cmsurl/}/index.html" class="a0">首页</a></li>

            {dede:channel type='top' row='6' currentstyle="<li class='selected'><a href='~typelink~' class='a~id~'>~typename~</a> </li>"}

     <li><a href='[field:typelink/]' class="a[field:id/]">[field:typename/]</a> </li>

    {/dede:channel}

            <!--li class="selected"><a href="#" class="a1">公司简介</a></li>

            <li><a href="#" class="a2">新闻动态</a></li>

            <li><a href="#" class="a3">公司荣誉</a></li>

            <li><a href="#" class="a4">产品介绍</a></li>

            <li><a href="#" class="a5">联系方式</a></li>

            <li><a href="#" class="a6">留言板</a></li-->

          </ul>

    58.织梦联动类别

    参考网址:http://cms.zz5u.net/dedecms/2010/0128/5284.html

    新页红酒: http://xinye.4006300457.com/

    59.织梦后台栏目用于导航菜单。

    第一种,新建公司简介的栏目,然后在高级选项-列表和文章模板选择你自己要用的模板,然后在栏目内容的地方填上该栏目要显示的内容,在模板内容调用处用{dede:field.content/}调用栏目内容;

    第二种,核心-单页文档管理-然后新建你需要的栏目内容,并选择相应模板,更新下、

    如果要在导航栏调用,就得对应栏目-更改-常规选项中-外部链接填填写上对应的单页地址即可。

    第三种,有的时候,如果公司简介、公司架构只是内容不同的话,完全可以把他们以文章形式发布,然后再导航相应位置调用,这个也可以实现、不过有的时候使用就不合适了。

    网站生成目录

    栏目描述

    相关文章   likearticle

    phpurl

    插件网址:

    分享                          http://www.jiathis.com/share/

    无觅相关文章插件               http://www.wumii.com/widget/relatedItems.htm

    织梦网址:

    织梦帮助文档                   http://help.dedecms.com/v53/

    51DEDECMS(模板堂)              http://www.51dedecms.com

    织梦吧                         http://www.dedecms8.com/

    峰峰blog(dede教程)           http://www.hdmhw.com/

    站长那些事                     http://www.dedeadmin.com

    萧涵seo                       http://www.xiaohanseo.com/

    ①用织梦dedecms做网站

    ②用wordpress博客做网站

    ③用论坛discuz!和phpwind做网站

    标签用法 网址:http://woshao.com/article/43156034afcc11e089d5000c2959fd2a/

    Apache下htaccess的配置:http://wenku.baidu.com/view/89541b160b4e767f5acfce1c.html

    phpurl

    插件网址:

    分享                          http://www.jiathis.com/share/

    无觅相关文章插件               http://www.wumii.com/widget/relatedItems.htm

    织梦网址:

    织梦帮助文档                   http://help.dedecms.com/v53/

    51DEDECMS(模板堂)              http://www.51dedecms.com

    织梦吧                         http://www.dedecms8.com/

    峰峰blog(dede教程)           http://www.hdmhw.com/

    萧涵seo                       http://www.xiaohanseo.com/

    站长那点事                    http://www.dedeadmin.com

    ①用织梦dedecms做网站

    ②用wordpress博客,z_blog做网站

    ③用论坛discuz!和phpwind做网站


    展开全文
  • {管理信息化 ERPMRP}浪 潮 erp 销售常见问题解说 辞参考 浪潮 ERP 销售常见问题解说辞 目录 浪潮 ERP 销售常见问题解说辞 2 目录2 文档说明 5 浪潮 ERP 销售常见问题解说辞 6 一.产品类 6 1.浪潮 PS 产品为什么搞 c/...
  • 源码依然开源发布,大家可以尽情二次开发。 产品性能:现在市场上的电话机器人最核心的功能就除了​‌‌有智能电话机器人话术配置,一键导入数据资料,根据时间设置进行外呼。还可以对筛选出意向客户进行按意向度...
  • 微擎的二次开发使用讲解

    万次阅读 多人点赞 2018-09-27 09:26:36
    公众号砸金蛋营销应用功能介绍 1 用户只能在微信里面打开 2 必须先关注公众号才能才加活动 (发模板) 3 同一个用户和同一个手机号码只能参加一 4 抽到红包发生奖金给用户,并发送模板消息给用户,用户可以点击再次...
  • 相比其他投入费用过高的营销方式,邮件营销以及低廉高效特点吸引了无数企业竞相使用,一有效的企业电子邮件营销能带来丰厚回报,如何避免EDM营销失败又能高效发挥其效果呢?我们总结出企业实际操作中遇到的常见...
  • 明基扫描仪二次开发包

    千次阅读 2002-06-06 09:40:00
    明基扫描仪二次开发包使用说明 明基电通信息技术有限公司·营销总部0512-68251233-2888目录一,功能说明(3-3)二,要求说明(3-3)三,开发包文件结构说明(3-4)四,scan.Dll接口说明(4-15)五,ImageRWSB.dll ...
  • 移动安全大黄书《Android应用安全防护和逆向分析》在开售不到一个月第一次印刷就销售完了,紧急开始了第二次印刷,感谢各位同学对本书的支持:关于这本书的内容之前已经介绍了,这里就就简单的大致说一下吧:本书...
  • 常见需求函数模型商品的最优价格,林承初,,商品的销售价格要依据产品成本和销售情况而定.常见的商品需求函数有线性函数、二次函数、指数函数等.在成本函数为已知的条件下
  • 想要从事互联网营销的朋友,那么有一些常见名词是不可不记,具体有哪些常见名词呢? CTR (Click Through Rate):点击率 具体公式:CTR=点击量/展现量 运营人员用来分析广告投放创意的质量,如果点击率较低,说明...
  • 【第节:ERP系统应用问题】 1、常见的数据问题 每到月末,财务部门的人总是特别忙,虽然有ERP系统在手,省掉不少事,但如果数据有问题,查起来也是一件挺费神的事。主要的数据问题在哪里呢?归纳起来有以下几类...
  • 常见的预测算法

    千次阅读 2018-01-11 11:22:29
    3,指数平滑法,包括 一次指数平滑法和二次指数平滑法,三次指数平滑法; 4,线性回归法,包括一元线性回归和二元线性回归,下面我一一的简单介绍一下各种方法。 ' i) G7 ?5 Q! R7 c: }5 x 一,简易平均法,
  • 沟通CTBS常见问题

    千次阅读 2015-02-02 17:00:50
     解决方法:联系相关销售渠道,获取和许可证匹配的激活码文件,修改文件名字为registry.dat,复制到ctbs server目录下的data文件夹里,重新启动系统服务中的ktlicservice服务即可,客户端退出重新登陆。     8、...
  • U8常见问题汇总

    千次阅读 2020-11-26 09:11:39
    U8常见问题汇总 1、帐套如何进行输出 系统管理——账套——输出; 2、帐套如何进行引入 开始——程序——用友ERP-U8——系统管理——操作员admin——密码791121——账套(找到备份的数据)——引入——**账套引入...
  • 病毒营销和裂变营销

    千次阅读 2020-10-21 16:19:34
    病毒营销 ...病毒营销是一种常见的网络营销方法,常用于进行网站推广、品牌推广等。由于这种传播是用户之间自发进行的,因此是几乎不需要费用的网络营销手段。 也就是说,病毒营销是通过提供有价值的
  • 常见版本管理工具

    千次阅读 2012-04-26 21:05:25
    、CVS 三、SVN 四、GIT 1. git命令行: 2. git设置 3. 上传文件过大的问题的解决办法: 4. 常见的.gitignore设置 5. 为git添加命令补全提示 附录一、linux下的SVN使用的简单流程 1. 第一把服务器代码...
  • 数据库常见笔试题

    万次阅读 2016-11-17 17:41:38
    数据库基础(面试常见题) 一、数据库基础 1. 数据抽象:物理抽象、概念抽象、视图级抽象,内模式、模式、外模式 2. SQL语言包括数据定义、数据操纵(Data Manipulation),数据控制(Data Control) 数据定义:Create ...
  • WAP常见问题问答大全

    万次阅读 2007-09-21 15:23:00
    目录 一、 关于WAP的常见问答、 关于WML的常见问答三、 关于WAP开发的常见问答四、关于WMLScript的常见问答五、关于WBMP的常见问答六、关于WAP网关的常见问答七、关于WAP浏览器的常见问答八、关于WAP手机的...
  • 前端常见面试题

    万次阅读 多人点赞 2018-09-26 19:48:35
    define是amd(异步模块加载机制)的api,第一个参数是模块名称(可选),第个参数是数组,包含所有依赖的模块(可选),第三个参数可以是一个函数或者是一个js对象。 (1) 如果第三个参数是回调函数的话,异步加载...
  • 关于WAP的常见问答

    千次阅读 2005-02-19 14:22:00
    WAP常见问题问答大全目录一、关于WAP的常见问答、关于WML的常见问答三、关于WAP开发的常见问答四、关于WMLScript的常见问答五、关于WBMP的常见问答六、关于WAP网关的常见问答七、关于WAP浏览器的常见问答八、关于...
  • 常见的广告收费模式

    千次阅读 2019-05-23 21:24:43
    常见广告收费模式大全  一个网络媒体(网站)会包含有数十个甚至成千上万个页面,网络广告所投放的位置和价格 就牵涉到特定的页面以及浏览人数的多寡。这好比平面媒体(如报纸)的“版位”、“发行 量”,或者电波媒体...
  • 数据库常见笔试面试题

    万次阅读 多人点赞 2013-10-31 10:17:47
    数据库基础(面试常见题) 一、数据库基础 1. 数据抽象:物理抽象、概念抽象、视图级抽象,内模式、模式、外模式 2. SQL语言包括数据定义、数据操纵(Data Manipulation),数据控制(Data Control) 数据定义:Create ...
  • WINCC 常见问题

    千次阅读 2012-12-23 20:09:09
    有一个值得主意的问题是此段代码的加入点,通过反复多的实践得出结论,即这个点必须加在始终显示于屏幕上的任何图形元素的属性中,这样才能达到语言报警的预期效果。 激情如火:引用加为好友发送留言 2005-11-...
  • kettle系列之常见问题

    万次阅读 2017-03-29 16:22:02
    开源ETL工具kettle系列之常见问题 摘要:本文主要介绍使用kettle设计一些ETL任务时一些常见问题,这些问题大部分都不在官方FAQ上,你可以在kettle的论坛上找到一些问题的答案 1. Join 我得到A 数据流(不管是...
  • Air系列模块常见问题列表

    万次阅读 2021-04-26 15:24:42
    是否支持xp系统   1.3.6、为什么提示多个工具在运行   1.3.7、为什么设备一直在正常运行,但是coolwatcher抓日志过程中,会突然不输出日志 、量产烧录工具使用问题 2.1、使用一拖多烧录时,出现后一个模块开始...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 46,272
精华内容 18,508
关键字:

常见的二次营销