【ubuntu18.04】ubuntu18.04安装EasyCwmp操作说明
参考链接
Tutorial – EasyCwmphttps://easycwmp.org/tutorial/
EasyCwmp 介绍
EasyCwmp 设计包括 2 个部分:
- EasyCwmp 核心:它包括 TR069 CWMP 引擎,负责与 ACS 服务器的通信。它是用 C 语言开发的。
- EasyCwmp DataModel:它包括 TR-06 的 DATAModel,并且符合一些 DataModel 标准,例如 TR-098、TR-181、TR-104 等。
关键设计目标是将 CWMP 方法执行与 CWMP 引擎分开。这使得添加和测试新功能变得容易。
DataModel 是使用 shell 作为免费解决方案和 C 作为商业解决方案开发的
EasyCwmp 依赖包
- libuci
- libcurl
- json-c
- libubox: minimum version [git version: 0608d1299546d4af1facc271a090cb2abb8c6105, date: 2012-05-30]
- libubus: minimum version [git version: a62e2f8c15a65efb1a82404d8f31e3bfc1cbe7d9, date: 2012-06-01]
- microxml: microxml is a fork of Mini-XML, it’s being used to parse XML blocks passed between ACS and the client and it’s published by freecwmp guys:
- microxml source: git clone https://github.com/pivasoftware/microxml.git
- microxml OpenWRT package: wget https://easycwmp.org/download/libmicroxml.tar.gz
安装工具包
apt install git
apt install wget
apt install curl
配置用户和组
新建AcsNet组
groupadd AcsNet
配置用户和组
USER=w1804
GROUP=AcsNet
说明:
w1804是用户名
AcsNet是组
创建安装目录git和dev
sudo mkdir -p /opt/{dev,git}
sudo chown -R $USER:$GROUP /opt/{dev,git}
安装json-c
clone代码到/opt/git/json-c目录
git clone git://github.com/json-c/json-c.git /opt/git/json-c
cd /opt/git/json-c/
mkdir build
cd build
配置
cmake ../CMakeLists.txt
../cmake-configure --prefix=/usr
编译
cd ..
make
安装
sudo make install
sudo ln -sf /usr/include/json-c /usr/include/json
安装libubox
clone源码
git clone git://nbd.name/luci2/libubox.git /opt/git/libubox
cd /opt/git/libubox/
配置
cmake CMakeLists.txt -DBUILD_LUA=OFF
编译
make
安装
sudo make install
sudo ln -sf /usr/local/lib/libubox.so /usr/lib/libubox.so
sudo mkdir -p /usr/share/libubox
sudo ln -sf /usr/local/share/libubox/jshn.sh /usr/share/libubox/jshn.sh
安装uci
clone源码
git clone git://nbd.name/uci.git /opt/git/uci
cd /opt/git/uci/
配置
cmake CMakeLists.txt -DBUILD_LUA=OFF
编译
make
安装
class="western"
sudo make install
sudo ln -sf /usr/local/bin/uci /sbin/uci
sudo ln -sf /usr/local/lib/libuci.so /usr/lib/libuci.so
安装libubox
clone源码
git clone git://nbd.name/luci2/libubox.git /opt/git/libubox
cd /opt/git/libubox/
配置
cmake CMakeLists.txt -DBUILD_LUA=OFF
编译
make
安装
sudo make install
sudo ln -sf /usr/local/lib/libubox.so /usr/lib/libubox.so
sudo mkdir -p /usr/share/libubox
sudo ln -sf /usr/local/share/libubox/jshn.sh /usr/share/libubox/jshn.sh
安装ubus
clone源码
git clone git://nbd.name/luci2/ubus.git /opt/git/ubus
cd /opt/git/ubus/
配置
cmake CMakeLists.txt -DBUILD_LUA=OFF
编译
make
安装
sudo make install
sudo ln -sf /usr/local/sbin/ubusd /usr/sbin/ubusd
sudo ln -sf /usr/local/lib/libubus.so /usr/lib/libubus.so
安装microxml
clone源码
git clone https://github.com/pivasoftware/microxml.git /opt/git/microxml
cd /opt/git/microxml/
配置
autoconf -i
./configure --prefix=/usr --enable-threads --enable-shared --enable-static
编译
make
安装
sudo make install
sudo ln -sf /usr/lib/libmicroxml.so.1.0 /lib/libmicroxml.so
sudo ln -sf /usr/lib/libmicroxml.so.1.0 /lib/libmicroxml.so.1
安装easycwmp
下载EasyCwmp
Download – EasyCwmphttps://easycwmp.org/get/
解压easycwmp
cd /opt/dev/
tar -xzvf easycwmp-1.8.6.tar.gz
mv easycwmp-easycwmp-1.8.6.tar.gz easycwmp
cd /opt/dev/easycwmp/
配置
autoreconf -i
./configure --enable-debug --enable-devel --enable-acs=multi --enable-jsonc=1
编译
make
easycwmp配置
我们不会安装 easycwmp,我们将从 /opt/dev/easycwmp/ 目录使用它。确保我们位于如下位置:
cd /opt/dev/easycwmp/
因为我们使用这个设置进行开发,所以我们希望我们所有的更改在我们的 git clone 中都是可见的。最好的方法是使用符号链接。首先创建脚本在实际设备上所在的目录:
sudo mkdir -p /usr/share/easycwmp/functions
sudo mkdir -p /etc/easycwmp
create symlinks for easycwmp scripts
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/easycwmp.sh /usr/sbin/easycwmp
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/defaults /usr/share/easycwmp/defaults
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/common /usr/share/easycwmp/functions/common
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/device_info /usr/share/easycwmp/functions/device_info
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/management_server /usr/share/easycwmp/functions/management_server
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/common/ipping_launch /usr/share/easycwmp/functions/ipping_launch
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/tr181/root /usr/share/easycwmp/functions/root
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/tr181/ip /usr/share/easycwmp/functions/ip
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/scripts/functions/tr181/ipping_diagnostic /usr/share/easycwmp/functions/ipping_diagnostic
修改权限
chmod +x /opt/dev/easycwmp/ext/openwrt/scripts/functions/*
创建软连接配置文件
sudo mkdir /etc/config
sudo ln -sf /opt/dev/easycwmp/ext/openwrt/config/easycwmp /etc/config/easycwmp
创建软连接easycwmpd
sudo ln -sf /opt/dev/easycwmp/bin/easycwmpd /usr/sbin/easycwmpd
导出环境变量
export UCI_CONFIG_DIR="/opt/dev/easycwmp/ext/openwrt/config/"
export UBUS_SOCKET="/var/run/ubus.sock"
安装sh脚本
sudo mkdir -p /lib/{config,functions}
sudo wget https://github.com/openwrt/openwrt/blob/main/package/base-files/files/lib/functions.sh -O /lib/functions.sh
sudo wget https://github.com/openwrt/openwrt/blob/main/package/system/uci/files/lib/config/uci.sh -O /lib/config/uci.sh
sudo wget https://github.com/openwrt/openwrt/blob/main/package/base-files/files/lib/functions/network.sh -O /lib/functions/network.sh
运行easycwmpd
export PATH=$PATH:/usr/sbin:/sbin
sudo ln -sf bash /bin/sh
/usr/sbin/ubusd -s /var/run/ubus.sock
/usr/sbin/easycwmpd -f -broot@w1804-virtual-machine:/opt/jboss-4.2.2.GA/bin# /usr/sbin/easycwmpd -f -b
2024-12-12 09:20:49 [easycwmp] NOTICE - add event '0 BOOTSTRAP'
2024-12-12 09:20:49 [easycwmp] NOTICE - add event '1 BOOT'
2024-12-12 09:20:49 [easycwmp] NOTICE - add event '2 PERIODIC'
2024-12-12 09:20:49 [easycwmp] NOTICE - external script init
2024-12-12 09:20:49 [easycwmp] NOTICE - init periodic inform: reference time = -62135615268, interval = 100
2024-12-12 09:20:49 [easycwmp] NOTICE - external: execute update_value_change
2024-12-12 09:20:49 [easycwmp] NOTICE - daemon started
2024-12-12 09:20:49 [easycwmp] NOTICE - external: execute inform device_id
2024-12-12 09:20:49 [easycwmp] NOTICE - external script exit
2024-12-12 09:20:49 [easycwmp] NOTICE - add event '1 BOOT'
2024-12-12 09:20:49 [easycwmp] NOTICE - http server initialized
2024-12-12 09:20:49 [easycwmp] NOTICE - entering main loop
2024-12-12 09:20:49 [easycwmp] NOTICE - start session
2024-12-12 09:20:49 [easycwmp] NOTICE - configured acs url http://192.168.1.110:8080/openacs/acs
2024-12-12 09:20:49 [easycwmp] NOTICE - external script init
2024-12-12 09:20:49 [easycwmp] NOTICE - external: execute inform parameter
2024-12-12 09:20:49 [easycwmp] NOTICE - send Inform
* Trying 192.168.1.110...
* TCP_NODELAY set
ubus call tr069 notify
测试
easycwmp get value
root@w1804-virtual-machine:/opt/jboss-4.2.2.GA/bin# easycwmp get value
{ "parameter": "Device.DeviceInfo.SpecVersion", "value": "1.0" }
{ "parameter": "Device.DeviceInfo.ProvisioningCode", "value": "" }
{ "parameter": "Device.DeviceInfo.Manufacturer", "value": "easycwmp" }
{ "parameter": "Device.DeviceInfo.ManufacturerOUI", "value": "FFFFFF" }
{ "parameter": "Device.DeviceInfo.ProductClass", "value": "easycwmp" }
{ "parameter": "Device.DeviceInfo.SerialNumber", "value": "FFFFFF123456" }
{ "parameter": "Device.DeviceInfo.HardwareVersion", "value": "example_hw_version" }
{ "parameter": "Device.DeviceInfo.SoftwareVersion", "value": "example_sw_version" }
{ "parameter": "Device.DeviceInfo.UpTime", "value": "6502", "type": "xsd:unsignedInt" }
{ "parameter": "Device.DeviceInfo.DeviceLog", "value": "" }
{ "parameter": "Device.DeviceInfo.MemoryStatus.Total", "value": "4015420" }
{ "parameter": "Device.DeviceInfo.MemoryStatus.Free", "value": "212392" }
{ "parameter": "Device.IP.Diagnostics.IPPing.DiagnosticsState", "value": "None" }
{ "parameter": "Device.IP.Diagnostics.IPPing.Host", "value": "" }
{ "parameter": "Device.IP.Diagnostics.IPPing.NumberOfRepetitions", "value": "3", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.Timeout", "value": "1000", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.DataBlockSize", "value": "64", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.SuccessCount", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.FailureCount", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.AverageResponseTime", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.MinimumResponseTime", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.IP.Diagnostics.IPPing.MaximumResponseTime", "value": "0", "type": "xsd:unsignedInt" }
{ "parameter": "Device.ManagementServer.URL", "value": "http:\/\/192.168.1.110:8080\/openacs\/acs" }
{ "parameter": "Device.ManagementServer.Username", "value": "easycwmp" }
{ "parameter": "Device.ManagementServer.Password", "value": "" }
{ "parameter": "Device.ManagementServer.PeriodicInformEnable", "value": "1", "type": "xsd:boolean" }
{ "parameter": "Device.ManagementServer.PeriodicInformInterval", "value": "100", "type": "xsd:unsignedInt" }
{ "parameter": "Device.ManagementServer.PeriodicInformTime", "value": "0001-01-01T00:00:00Z", "type": "xsd:dateTime" }
{ "parameter": "Device.ManagementServer.ConnectionRequestURL", "value": "" }
{ "parameter": "Device.ManagementServer.ConnectionRequestUsername", "value": "easycwmp" }
{ "parameter": "Device.ManagementServer.ConnectionRequestPassword", "value": "" }
{ "parameter": "Device.ManagementServer.ParameterKey", "value": "" }
相关文章:
【ubuntu18.04】ubuntu18.04安装EasyCwmp操作说明
参考链接 Tutorial – EasyCwmphttps://easycwmp.org/tutorial/ EasyCwmp 介绍 EasyCwmp 设计包括 2 个部分: EasyCwmp 核心:它包括 TR069 CWMP 引擎,负责与 ACS 服务器的通信。它是用 C 语言开发的。EasyCwmp DataModel:它包…...
使用Jackson库的ObjectMapper类将JSON字符串转换为Java的Map对象
本教程展示如何使用Jackson库的ObjectMapper类将JSON字符串转换为Java的Map对象。 下面是具体的步骤和代码示例,包括添加依赖项以及编写用于反序列化JSON字符串为Map的代码。 添加依赖项 首先,在你的项目中添加Jackson库的依赖。如果你使用的是Maven构…...
ASP.NET Core实现鉴权授权的几个库
System.IdentityModel.Tokens.Jwt 和 Microsoft.AspNetCore.Authentication.JwtBearer 是两个常用的库,分别用于处理 JWT(JSON Web Token)相关的任务。它们在功能上有一定重叠,但侧重点和使用场景有所不同。 1. System.IdentityM…...
MySql:数据类型
✨✨作者主页:嶔某✨✨ ✨✨所属专栏:MySql✨✨ 数据类型分类 分类数据类型说明数值类型BIT(M)位类型,M指定位数,默认值1,范围1~64TINYINT [UNSIGNED]占用一个字节,带符号的范围 -128~127,无符…...
Couchbase的OLAP支持情况
Couchbase 是一个高性能的 NoSQL 数据库,主要用于在线事务处理(OLTP)场景,但它也提供了一些功能来支持在线分析处理(OLAP)需求。以下是 Couchbase 对 OLAP 支持的几个方面: 1. N1QL 查询语言 …...
企业级包管理器之搭建 npm 私有服务器 (6)
在企业级应用开发中,常常需要处理私有包的发布和管理。搭建 npm 私有服务器是一个理想的解决方案,它不仅能保证代码的私密性,还能提供更快的下载速度和更精细的权限设置。 一、搭建 npm 私有服务器的优势 保证代码私密性:在企业…...
Elasticsearch的一些介绍
你想问的可能是 **Elasticsearch**,以下是关于它的一些介绍: ### 概述 Elasticsearch是一个基于Apache Lucene库构建的开源分布式搜索和分析引擎,采用Java语言编写,具有高性能、可扩展性和易用性等特点,可用于各种数据…...
音乐网站设计与实现
文末获取源码和万字论文,制作不易,感谢点赞支持。 音乐网站设计与实现 摘 要 本音乐网站是针对目前音乐网站管理的实际需求,从实际工作出发,对过去的音乐网站管理系统存在的问题进行分析,结合计算机系统的结构、概念、…...
UE5 蓝图节点中文化
文章目录 一、问题背景二、解决方法 一、问题背景 在虚幻引擎5.4、5.5版本中,即使将编辑器语言设置为中文,还是会出现大部分蓝图节点没有中文化。 蓝图节点没有中文化图示: 二、解决方法 在左上角找到 编辑,打开 编辑器偏好设置…...
java抽奖系统登录下(四)
6.4 关于登录 最简单的登录: 1、web登录页填写登录信息,前端发送登录信息到后端; 2、后端接受登录信息,并校验。校验成功,返回成功结果。 这种登录会出现一个问题,用户1成功登录之后,获取到后台…...
解决阿里云轻量级服务器 Ubuntu 24.04.1 LTS 没网也 ping 不通 8.8.8.8 以及 route -n 没有输出任何转发信息
事情发生在两天前,位于公网的阿里云轻量级服务器(Ubuntu 24.04.1 LTS)忽然没网。主要是上次上服务器进行配置已经是一个多月前,最近也没有做什么事情,就忽然没网了,让人纳闷。更主要的是,上次备…...
跨域问题及其解决方案
跨域问题及其解决方案 在Web开发中,跨域问题是一个常见的安全限制,它涉及到浏览器的同源策略(Same-Origin Policy)。本文将详细解释跨域问题的原因、影响以及几种常见的解决方案,并提供在Java中的实现方法。 目录 跨…...
在CentOS中安装和卸载mysql
在CentOS7中安装和卸载mysql 卸载mysql1、查看是否安装过mysql2、查看mysql服务状态3、关闭mysql服务4、卸载mysql相关的rpm程序5、删除mysql相关的文件6、删除mysql的配置文件my.cnf 安装mysql1、下载mysql相关的rpm程序2、检查/tmp临时目录权限3、安装mysql前的依赖检查3、安…...
React简单入门 - [Next.js项目] - 页面跳转、AntD组件、二级目录等
须知 1Next.js 官网(英文)https://nextjs.org/2Next.js 文档(中文)https://nextjscn.org/docs/3Ant Design组件总览https://ant-design.antgroup.com/components/overview-cn4tailwindcss类名大全 官网https://www.tailwindcss.cn/docs/justify-content 5tailwindcss常用类…...
Redis安装和Python练习(Windows11 + Python3.X + Pycharm社区版)
环境 Windows11 Python3.X Pycharm社区版 思路 1 github下载redis压缩包 ,安装并启动redis服务,在客户端连接redis服务。 2 在pycharm中运行python程序,连接redis服务,熟悉redis的使用和巩固python语言。 3 python开发环境…...
Sqoop脚本编写(Mysql---->>hdfs)
目录 语法手册编写方式脚本文件类型文件编写.jar路径指定 执行效果执行方式效果 语法手册 参考博客 编写方式 脚本文件类型 只要是可读的文件即可(.txt或者.sh等其他类型,不带文件后缀也可以,但二进制文件最好不要) 文件编写…...
帝可得项目redis连接不上
首先我一切配置都没问题: 1. redis-server启动 2. 可视化界面显示redis已连接 原因: 不知道是不是因为不同版本的问题(因为我之前的sky就没这个问题) 这里把password改成auth就可以了...
JS中this的值详细讲解以及面试指向练习
this 的值取决于它出现的上下文:函数、类或全局。 在函数内部,this 的值取决于函数如何被调用,this 是语言在函数体被执行时为你创建的绑定 对于典型的函数,this 的值是函数被访问的对象。换句话说,如果函数调用的形…...
显示浮动式窗口的方法
文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了AlertDialog Widget相关的内容,本章回中将介绍BottomSheet Widget.闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的BottomSheet是一种弹出式窗口,和上一章回中介绍的AlertDialog类似,但是也…...
FireFox火狐浏览器企业策略禁止更新
一直在用火狐浏览器,但是经常提示更新,进入浏览器右上角就弹出提示,比较烦。多方寻找,一直没有找到合适的方案,毕竟官方没有给出禁用检查更新的选项,甚至about:config里都没有。 最终找到了通过企业策略控…...
C++类的运算符重载
目标 让自定义的类直接使用运算符运算 代码 头文件及类定义 #include <iostream>using namespace std; class Complex {int rel;int vir; public:void show(){cout <<"("<<this->rel<<","<<this->vir<<&quo…...
泷羽Sec学习笔记-zmap搭建炮台
zmap搭建炮台 zmap扫描环境:kali-linux 先更新软件库 sudo apt update 下载zmap sudo apt install zmap 开始扫描(需要root权限) sudo zmap -p 80 -o raw_ips.txt 代码解析: sudo:以超级用户(管理员)权限运行…...
分析M0G突破后急剧下跌内因,x.game阐述不利面延续多久
MOG最新消息显示,美国唐纳德-的一则声明公开表示支持一种基于以太坊网络ERC-20代币标准的病毒式meme代币——Mog Coin(MOG),这一消息迅速发酵。然而,令人意想不到的是,在这位全球知名政治人物的背书之后&am…...
网络爬虫全解析
一、网络爬虫基础要点 (一)爬虫原理 目标确定:明确需要抓取数据的网站或网页范围,例如针对特定电商平台抓取商品信息,或聚焦新闻网站获取新闻报道内容,要考量数据的价值与用途。URL 解析:理解网…...
《孤岛惊魂4》无法启动提示缺少“msvcp100.dll”快速修复方法!
《孤岛惊魂4》缺少msvcp100.dll的解决之道 在探索《孤岛惊魂4》这款充满惊险与刺激的射击游戏时,玩家可能会遇到一些意外的障碍,其中之一便是“缺少msvcp100.dll”的错误提示。这个错误不仅让游戏无法正常启动,还可能让玩家对游戏的热情大打…...
GS-SLAM论文阅读--RGBDS-SLAM
前言 最近GS-SLAM领域的工作层出不穷,有很多不错的工作出现。接下来慢慢写一下相关博客。 文章目录 前言1.背景介绍2.关键内容2.1 3D多层次金字塔高斯喷溅2.2 紧密耦合多特征重构优化2.3总体流程 3.文章贡献4.个人思考 1.背景介绍 高保真重建是密集SLAM的关键。最…...
条件编译->enable_if和 if constexpr使用区别
enable_if 和 if constexpr 是 C 中用于控制编译或运行时条件的重要工具,它们各有不同的用途和使用场景。以下是它们的主要区别: 1. enable_if std::enable_if 是一个类型特征,用于在编译时根据条件选择类型。常用于模板元编程,…...
介绍一下CSS中伪类和伪元素的概念
一、伪类(Pseudo - Classes) 1. 定义 伪类是添加到选择器的关键字,用于定义元素的特殊状态。这些状态不是由文档树中的结构或属性来表示,而是基于用户行为(如鼠标悬停)、元素状态(如被选中&am…...
【橘子ES】熔断器Circuit breaker
一、相关概念 我们在日常的开发中,关于服务之间的熔断操作似乎很常见,当请求超过了我们服务所认为可以承受的一个上限阈值的时候,我们为了保护服务不会被进一步的高负载压崩溃,我们有时候会选择熔断请求,此时服务不再…...
6.4 CPU性能分析--Intel处理器跟踪技术
Intel处理器跟踪PT技术是记录程序执行过程的技术,它把记录信息编码报文存到高压缩率的二进制文件中。该二进制文件结合每条指令的时间戳重建执行流。PT技术覆盖度大,开销小,有关开销的信息详见,主要用于性能问题的事后分析和根因定…...
机械厂网站模板/国际购物网站平台有哪些
很多初学者问小编是如何学习Java的,有没有好的建议? 今天给大家来点干货,因此咱们就不说一些学习方法和技巧了,直接来谈每个阶段要学习的内容甚至是一些书籍。这一部分的内容,同样适用于一些希望转行到Java的同学。 对…...
网站做百度竞价/信息流广告接单平台
点击打开链接 在发生其他类或对象关注的事情时,类或对象可通过事件通知它们。发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。 事件概述 事件具有以下特点: l 发行者确…...
白银市建设局网站王浩/管理培训班
10月1日-10月7日,我们携手8家战略媒体,99家合作媒体,开展了“国庆soulmate寻缘之旅”为期七天的活动。 突破以往的活动形式, 国庆寻缘之旅分为三个阶段“初识”、“相知”、“相恋”,从陌生到熟悉,让寻缘的…...
邢台网站建设服务周到/凡科建站
【2018.02】劳特利奇国防研究手册(第一版)Routledge Handbook of Defence Studies,共412页。 如果需要电子版,请联系QQ:3042075372。 Routledge是英国的一家跨国出版社,总部设在伦敦,主要在伦敦…...
wordpress图库主题/seo优化的优点
Intent(意图) 将一个复杂对象的构建(construction)与其表示(representation)分离,这样同样的构建过程可以创建出不同的表示。 Motivation(动机) 一个RTF(R…...
具有设计感的网站/湘潭网页设计
前段时间和一个朋友聊天,酒席间向我抱怨他那段时间的郁闷:项目经理从客户那里拿来一个需求,实际上就是一个ppt描述,我这个朋友拿过来看后刚开始不觉得什么,一个通常的网站系统又能复杂的了哪去,但是越往后做就越发觉得…...