优化安装脚本
优化SelectPage编辑时按顺序显示 优化分类、省市联动列表接口逻辑
正在显示
9 个修改的文件
包含
68 行增加
和
71 行删除
@@ -20,14 +20,15 @@ FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。 | @@ -20,14 +20,15 @@ FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。 | ||
20 | * 强大的插件扩展功能,在线安装卸载升级插件 | 20 | * 强大的插件扩展功能,在线安装卸载升级插件 |
21 | * 通用的会员模块和API模块 | 21 | * 通用的会员模块和API模块 |
22 | * 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证 | 22 | * 共用同一账号体系的Web端会员中心权限验证和API接口会员权限验证 |
23 | -* 二级域名部署支持,同时域名支持绑定到插件 | 23 | +* 二级域名部署支持,同时域名支持绑定到应用插件 |
24 | * 多语言支持,服务端及客户端支持 | 24 | * 多语言支持,服务端及客户端支持 |
25 | * 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩 | 25 | * 支持大文件分片上传、剪切板粘贴上传、拖拽上传,进度条显示,图片上传前压缩 |
26 | -* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[博客](https://www.fastadmin.net/store/blog.html)、[知识付费问答](https://www.fastadmin.net/store/ask.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[商城系统](https://www.fastadmin.net/store/shopro.html)) | 26 | +* 支持表格固定列、固定表头、跨页选择、Excel导出、模板渲染等功能 |
27 | +* 强大的第三方应用模块支持([CMS](https://www.fastadmin.net/store/cms.html)、[博客](https://www.fastadmin.net/store/blog.html)、[知识付费问答](https://www.fastadmin.net/store/ask.html)、[在线投票系统](https://www.fastadmin.net/store/vote.html)、[B2C商城](https://www.fastadmin.net/store/shopro.html)、[B2B2C商城](https://www.fastadmin.net/store/wanlshop.html)) | ||
27 | * 支持CMS、博客、知识付费问答无缝整合[Xunsearch全文搜索](https://www.fastadmin.net/store/xunsearch.html) | 28 | * 支持CMS、博客、知识付费问答无缝整合[Xunsearch全文搜索](https://www.fastadmin.net/store/xunsearch.html) |
28 | -* 第三方小程序支持([预订小程序](https://www.fastadmin.net/store/ball.html)、[问答小程序](https://www.fastadmin.net/store/questions.html)、[活动报名小程序](https://www.fastadmin.net/store/huodong.html)、[商城小程序](https://www.fastadmin.net/store/xshop.html)、[博客小程序](https://www.fastadmin.net/store/blog.html)) | 29 | +* 第三方小程序支持([CMS小程序](https://www.fastadmin.net/store/cms.html)、[预订小程序](https://www.fastadmin.net/store/ball.html)、[问答小程序](https://www.fastadmin.net/store/ask.html)、[点餐小程序](https://www.fastadmin.net/store/unidrink.html)、[B2C小程序](https://www.fastadmin.net/store/shopro.html)、[B2B2C小程序](https://www.fastadmin.net/store/wanlshop.html)、[博客小程序](https://www.fastadmin.net/store/blog.html)) |
29 | * 整合第三方短信接口(阿里云、腾讯云短信) | 30 | * 整合第三方短信接口(阿里云、腾讯云短信) |
30 | -* 无缝整合第三方云存储(七牛云、阿里云OSS、又拍云)功能 | 31 | +* 无缝整合第三方云存储(七牛云、阿里云OSS、又拍云)功能,支持云储存分片上传 |
31 | * 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器) | 32 | * 第三方富文本编辑器支持(Summernote、Kindeditor、百度编辑器) |
32 | * 第三方登录(QQ、微信、微博)整合 | 33 | * 第三方登录(QQ、微信、微博)整合 |
33 | * 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付 | 34 | * 第三方支付(微信、支付宝)无缝整合,微信支持PC端扫码支付 |
@@ -48,7 +49,7 @@ https://demo.fastadmin.net | @@ -48,7 +49,7 @@ https://demo.fastadmin.net | ||
48 | 提 示:演示站数据无法进行修改,请下载源码安装体验全部功能 | 49 | 提 示:演示站数据无法进行修改,请下载源码安装体验全部功能 |
49 | 50 | ||
50 | ## 界面截图 | 51 | ## 界面截图 |
51 | -![控制台](https://gitee.com/uploads/images/2017/0411/113717_e99ff3e7_10933.png "控制台") | 52 | +![控制台](https://images.gitee.com/uploads/images/2020/0929/202947_8db2d281_10933.gif "控制台") |
52 | 53 | ||
53 | ## 问题反馈 | 54 | ## 问题反馈 |
54 | 55 |
@@ -90,7 +90,10 @@ class Install extends Command | @@ -90,7 +90,10 @@ class Install extends Command | ||
90 | $this->request = Request::instance(); | 90 | $this->request = Request::instance(); |
91 | 91 | ||
92 | define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS); | 92 | define('INSTALL_PATH', APP_PATH . 'admin' . DS . 'command' . DS . 'Install' . DS); |
93 | - Lang::load(INSTALL_PATH . $this->request->langset() . '.php'); | 93 | + $langSet = $this->request->langset(); |
94 | + if ($langSet === 'zh-cn') { | ||
95 | + Lang::load(INSTALL_PATH . $langSet . '.php'); | ||
96 | + } | ||
94 | 97 | ||
95 | $installLockFile = INSTALL_PATH . "install.lock"; | 98 | $installLockFile = INSTALL_PATH . "install.lock"; |
96 | 99 | ||
@@ -196,23 +199,19 @@ class Install extends Command | @@ -196,23 +199,19 @@ class Install extends Command | ||
196 | // 后台入口文件 | 199 | // 后台入口文件 |
197 | $adminFile = ROOT_PATH . 'public' . DS . 'admin.php'; | 200 | $adminFile = ROOT_PATH . 'public' . DS . 'admin.php'; |
198 | 201 | ||
199 | - // 数据库配置文件 | ||
200 | - $dbConfigFile = APP_PATH . 'database.php'; | ||
201 | - $config = @file_get_contents($dbConfigFile); | 202 | + // 生成数据库Env配置文件 |
203 | + $envFile = ROOT_PATH . '.env.sample'; | ||
204 | + $envStr = @file_get_contents($envFile); | ||
202 | $callback = function ($matches) use ($mysqlHostname, $mysqlHostport, $mysqlUsername, $mysqlPassword, $mysqlDatabase, $mysqlPrefix) { | 205 | $callback = function ($matches) use ($mysqlHostname, $mysqlHostport, $mysqlUsername, $mysqlPassword, $mysqlDatabase, $mysqlPrefix) { |
203 | $field = "mysql" . ucfirst($matches[1]); | 206 | $field = "mysql" . ucfirst($matches[1]); |
204 | $replace = $$field; | 207 | $replace = $$field; |
205 | - if ($matches[1] == 'hostport' && $mysqlHostport == 3306) { | ||
206 | - $replace = ''; | ||
207 | - } | ||
208 | - return "'{$matches[1]}'{$matches[2]}=>{$matches[3]}Env::get('database.{$matches[1]}', '{$replace}'),"; | 208 | + return "{$matches[1]} = {$replace}" . PHP_EOL; |
209 | }; | 209 | }; |
210 | - $config = preg_replace_callback("/'(hostname|database|username|password|hostport|prefix)'(\s+)=>(\s+)Env::get\((.*)\)\,/", $callback, $config); | 210 | + $envConf = preg_replace_callback('/(hostname|database|username|password|hostport|prefix)\s*=\s*(.*?)\n/', $callback, $envStr); |
211 | 211 | ||
212 | - // 检测能否成功写入数据库配置 | ||
213 | - $result = @file_put_contents($dbConfigFile, $config); | 212 | + $result = @file_put_contents(ROOT_PATH . '.env', $envConf); |
214 | if (!$result) { | 213 | if (!$result) { |
215 | - throw new Exception(__('The current permissions are insufficient to write the file %s', 'application/database.php')); | 214 | + throw new Exception(__('The current permissions are insufficient to write the file %s', '.env')); |
216 | } | 215 | } |
217 | 216 | ||
218 | // 变更默认管理员密码 | 217 | // 变更默认管理员密码 |
@@ -222,6 +221,12 @@ class Install extends Command | @@ -222,6 +221,12 @@ class Install extends Command | ||
222 | $newPassword = md5(md5($adminPassword) . $newSalt); | 221 | $newPassword = md5(md5($adminPassword) . $newSalt); |
223 | $data = ['username' => $adminUsername, 'email' => $adminEmail, 'password' => $newPassword, 'salt' => $newSalt]; | 222 | $data = ['username' => $adminUsername, 'email' => $adminEmail, 'password' => $newPassword, 'salt' => $newSalt]; |
224 | $instance->name('admin')->where('username', 'admin')->update($data); | 223 | $instance->name('admin')->where('username', 'admin')->update($data); |
224 | + | ||
225 | + // 变更前台默认用户的密码,随机生成 | ||
226 | + $newSalt = substr(md5(uniqid(true)), 0, 6); | ||
227 | + $newPassword = md5(md5(Random::alnum(8)) . $newSalt); | ||
228 | + $instance->name('user')->where('username', 'admin')->update(['password' => $newPassword, 'salt' => $newSalt]); | ||
229 | + | ||
225 | // 修改后台入口 | 230 | // 修改后台入口 |
226 | $adminName = ''; | 231 | $adminName = ''; |
227 | if (is_file($adminFile)) { | 232 | if (is_file($adminFile)) { |
@@ -230,9 +235,9 @@ class Install extends Command | @@ -230,9 +235,9 @@ class Install extends Command | ||
230 | } | 235 | } |
231 | 236 | ||
232 | //修改站点名称 | 237 | //修改站点名称 |
233 | - if ($siteName != __('My Website')) { | 238 | + if ($siteName != config('site.name')) { |
234 | $instance->name('config')->where('name', 'name')->update(['value' => $siteName]); | 239 | $instance->name('config')->where('name', 'name')->update(['value' => $siteName]); |
235 | - $configFile = APP_PATH . 'extra' . DS . 'site.php'; | 240 | + $configFile = CONF_PATH . 'extra' . DS . 'site.php'; |
236 | $config = include $configFile; | 241 | $config = include $configFile; |
237 | $configList = $instance->name("config")->select(); | 242 | $configList = $instance->name("config")->select(); |
238 | foreach ($configList as $k => $value) { | 243 | foreach ($configList as $k => $value) { |
@@ -270,17 +275,15 @@ class Install extends Command | @@ -270,17 +275,15 @@ class Install extends Command | ||
270 | 'public' . DS . 'assets' . DS . 'libs' | 275 | 'public' . DS . 'assets' . DS . 'libs' |
271 | ]; | 276 | ]; |
272 | 277 | ||
273 | - //数据库配置文件 | ||
274 | - $dbConfigFile = APP_PATH . 'database.php'; | ||
275 | - | ||
276 | - if (version_compare(PHP_VERSION, '5.5.0', '<')) { | ||
277 | - throw new Exception(__("The current version %s is too low, please use PHP 5.5 or higher", PHP_VERSION)); | 278 | + if (version_compare(PHP_VERSION, '7.0.0', '<')) { |
279 | + throw new Exception(__("The current version %s is too low, please use PHP 7.0 or higher", PHP_VERSION)); | ||
278 | } | 280 | } |
279 | if (!extension_loaded("PDO")) { | 281 | if (!extension_loaded("PDO")) { |
280 | throw new Exception(__("PDO is not currently installed and cannot be installed")); | 282 | throw new Exception(__("PDO is not currently installed and cannot be installed")); |
281 | } | 283 | } |
282 | - if (!is_really_writable($dbConfigFile)) { | ||
283 | - throw new Exception(__('The current permissions are insufficient to write the configuration file application/database.php')); | 284 | + $envConfFile = ROOT_PATH . '.env'; |
285 | + if (is_file($envConfFile) && !is_really_writable($envConfFile)) { | ||
286 | + throw new Exception(__('The current permissions are insufficient to write the file %s', '.env')); | ||
284 | } | 287 | } |
285 | foreach ($checkDirs as $k => $v) { | 288 | foreach ($checkDirs as $k => $v) { |
286 | if (!is_dir(ROOT_PATH . $v)) { | 289 | if (!is_dir(ROOT_PATH . $v)) { |
@@ -8,10 +8,10 @@ return [ | @@ -8,10 +8,10 @@ return [ | ||
8 | 'Mysql Password' => 'MySQL 密码', | 8 | 'Mysql Password' => 'MySQL 密码', |
9 | 'Mysql Prefix' => 'MySQL 数据表前缀', | 9 | 'Mysql Prefix' => 'MySQL 数据表前缀', |
10 | 'Mysql Hostport' => 'MySQL 端口号', | 10 | 'Mysql Hostport' => 'MySQL 端口号', |
11 | - 'Admin Username' => '管理者用户名', | ||
12 | - 'Admin Email' => '管理者Email', | ||
13 | - 'Admin Password' => '管理者密码', | ||
14 | - 'Repeat Password' => '重复密码', | 11 | + 'Admin Username' => '管理员用户名', |
12 | + 'Admin Email' => '管理员Email', | ||
13 | + 'Admin Password' => '管理员密码', | ||
14 | + 'Repeat Password' => '重复管理员密码', | ||
15 | 'Website' => '网站名称', | 15 | 'Website' => '网站名称', |
16 | 'My Website' => '我的网站', | 16 | 'My Website' => '我的网站', |
17 | 'Install now' => '点击安装', | 17 | 'Install now' => '点击安装', |
@@ -26,9 +26,9 @@ return [ | @@ -26,9 +26,9 @@ return [ | ||
26 | 'Please input correct password' => '密码长度必须在6-16位之间,不能包含空格', | 26 | 'Please input correct password' => '密码长度必须在6-16位之间,不能包含空格', |
27 | 'The two passwords you entered did not match' => '两次输入的密码不一致', | 27 | 'The two passwords you entered did not match' => '两次输入的密码不一致', |
28 | 'Please input correct website' => '网站名称输入不正确', | 28 | 'Please input correct website' => '网站名称输入不正确', |
29 | - 'The current version %s is too low, please use PHP 5.5 or higher' => '当前版本%s过低,请使用PHP5.5以上版本', | 29 | + 'The current version %s is too low, please use PHP 7.0 or higher' => '当前版本%s过低,请使用PHP7.0以上版本', |
30 | 'PDO is not currently installed and cannot be installed' => '当前未开启PDO,无法进行安装', | 30 | 'PDO is not currently installed and cannot be installed' => '当前未开启PDO,无法进行安装', |
31 | 'The current permissions are insufficient to write the file %s' => '当前权限不足,无法写入文件%s', | 31 | 'The current permissions are insufficient to write the file %s' => '当前权限不足,无法写入文件%s', |
32 | 'Please go to the official website to download the full package or resource package and try to install' => '当前代码仅包含核心代码,请前往官网下载完整包或资源包覆盖后再尝试安装', | 32 | 'Please go to the official website to download the full package or resource package and try to install' => '当前代码仅包含核心代码,请前往官网下载完整包或资源包覆盖后再尝试安装', |
33 | 'The system has been installed. If you need to reinstall, please remove %s first' => '当前已经安装成功,如果需要重新安装,请手动移除%s文件', | 33 | 'The system has been installed. If you need to reinstall, please remove %s first' => '当前已经安装成功,如果需要重新安装,请手动移除%s文件', |
34 | -]; | ||
34 | +]; |
@@ -29,7 +29,7 @@ class Ajax extends Backend | @@ -29,7 +29,7 @@ class Ajax extends Backend | ||
29 | parent::_initialize(); | 29 | parent::_initialize(); |
30 | 30 | ||
31 | //设置过滤方法 | 31 | //设置过滤方法 |
32 | - $this->request->filter(['strip_tags', 'htmlspecialchars']); | 32 | + $this->request->filter(['trim', 'strip_tags', 'htmlspecialchars']); |
33 | } | 33 | } |
34 | 34 | ||
35 | /** | 35 | /** |
@@ -138,8 +138,8 @@ class Ajax extends Backend | @@ -138,8 +138,8 @@ class Ajax extends Backend | ||
138 | $orderway = $orderway == 'asc' ? 'ASC' : 'DESC'; | 138 | $orderway = $orderway == 'asc' ? 'ASC' : 'DESC'; |
139 | $sour = $weighdata = []; | 139 | $sour = $weighdata = []; |
140 | $ids = explode(',', $ids); | 140 | $ids = explode(',', $ids); |
141 | - $prikey = $pk ? $pk : (Db::name($table)->getPk() ?: 'id'); | ||
142 | - $pid = $this->request->post("pid"); | 141 | + $prikey = $pk && preg_match("/^[a-z0-9\-_]+$/i", $pk) ? $pk : (Db::name($table)->getPk() ?: 'id'); |
142 | + $pid = $this->request->post("pid", ""); | ||
143 | //限制更新的字段 | 143 | //限制更新的字段 |
144 | $field = in_array($field, ['weigh']) ? $field : 'weigh'; | 144 | $field = in_array($field, ['weigh']) ? $field : 'weigh'; |
145 | 145 | ||
@@ -217,20 +217,20 @@ class Ajax extends Backend | @@ -217,20 +217,20 @@ class Ajax extends Backend | ||
217 | */ | 217 | */ |
218 | public function category() | 218 | public function category() |
219 | { | 219 | { |
220 | - $type = $this->request->get('type'); | ||
221 | - $pid = $this->request->get('pid'); | 220 | + $type = $this->request->get('type', ''); |
221 | + $pid = $this->request->get('pid', ''); | ||
222 | $where = ['status' => 'normal']; | 222 | $where = ['status' => 'normal']; |
223 | - $categorylist = null; | 223 | + $categorylist = null; |
224 | if ($pid || $pid === '0') { | 224 | if ($pid || $pid === '0') { |
225 | $where['pid'] = $pid; | 225 | $where['pid'] = $pid; |
226 | } | 226 | } |
227 | if ($type) { | 227 | if ($type) { |
228 | $where['type'] = $type; | 228 | $where['type'] = $type; |
229 | } | 229 | } |
230 | - | 230 | + |
231 | $categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select(); | 231 | $categorylist = Db::name('category')->where($where)->field('id as value,name')->order('weigh desc,id desc')->select(); |
232 | 232 | ||
233 | - $this->success('', null, $categorylist); | 233 | + $this->success('', '', $categorylist); |
234 | } | 234 | } |
235 | 235 | ||
236 | /** | 236 | /** |
@@ -241,27 +241,23 @@ class Ajax extends Backend | @@ -241,27 +241,23 @@ class Ajax extends Backend | ||
241 | $params = $this->request->get("row/a"); | 241 | $params = $this->request->get("row/a"); |
242 | if (!empty($params)) { | 242 | if (!empty($params)) { |
243 | $province = isset($params['province']) ? $params['province'] : ''; | 243 | $province = isset($params['province']) ? $params['province'] : ''; |
244 | - $city = isset($params['city']) ? $params['city'] : null; | 244 | + $city = isset($params['city']) ? $params['city'] : ''; |
245 | } else { | 245 | } else { |
246 | - $province = $this->request->get('province'); | ||
247 | - $city = $this->request->get('city'); | 246 | + $province = $this->request->get('province', ''); |
247 | + $city = $this->request->get('city', ''); | ||
248 | } | 248 | } |
249 | $where = ['pid' => 0, 'level' => 1]; | 249 | $where = ['pid' => 0, 'level' => 1]; |
250 | $provincelist = null; | 250 | $provincelist = null; |
251 | if ($province !== '') { | 251 | if ($province !== '') { |
252 | - if ($province) { | ||
253 | - $where['pid'] = $province; | ||
254 | - $where['level'] = 2; | ||
255 | - } | 252 | + $where['pid'] = $province; |
253 | + $where['level'] = 2; | ||
256 | if ($city !== '') { | 254 | if ($city !== '') { |
257 | - if ($city) { | ||
258 | - $where['pid'] = $city; | ||
259 | - $where['level'] = 3; | ||
260 | - } | ||
261 | - $provincelist = Db::name('area')->where($where)->field('id as value,name')->select(); | 255 | + $where['pid'] = $city; |
256 | + $where['level'] = 3; | ||
262 | } | 257 | } |
263 | } | 258 | } |
264 | - $this->success('', null, $provincelist); | 259 | + $provincelist = Db::name('area')->where($where)->field('id as value,name')->select(); |
260 | + $this->success('', '', $provincelist); | ||
265 | } | 261 | } |
266 | 262 | ||
267 | /** | 263 | /** |
@@ -189,7 +189,7 @@ class Config extends Backend | @@ -189,7 +189,7 @@ class Config extends Backend | ||
189 | $config[$value['name']] = $value['value']; | 189 | $config[$value['name']] = $value['value']; |
190 | } | 190 | } |
191 | file_put_contents( | 191 | file_put_contents( |
192 | - APP_PATH . 'extra' . DS . 'site.php', | 192 | + CONF_PATH . 'extra' . DS . 'site.php', |
193 | '<?php' . "\n\nreturn " . var_export_short($config) . ";\n" | 193 | '<?php' . "\n\nreturn " . var_export_short($config) . ";\n" |
194 | ); | 194 | ); |
195 | } | 195 | } |
@@ -535,25 +535,22 @@ class Backend extends Controller | @@ -535,25 +535,22 @@ class Backend extends Controller | ||
535 | } | 535 | } |
536 | 536 | ||
537 | $fields = is_array($this->selectpageFields) ? $this->selectpageFields : ($this->selectpageFields && $this->selectpageFields != '*' ? explode(',', $this->selectpageFields) : []); | 537 | $fields = is_array($this->selectpageFields) ? $this->selectpageFields : ($this->selectpageFields && $this->selectpageFields != '*' ? explode(',', $this->selectpageFields) : []); |
538 | - | 538 | + |
539 | //如果有primaryvalue,说明当前是初始化传值,按照选择顺序排序 | 539 | //如果有primaryvalue,说明当前是初始化传值,按照选择顺序排序 |
540 | - if ($primaryvalue !== null) { | 540 | + if ($primaryvalue !== null && preg_match("/^[a-z0-9_\-]+$/i", $primarykey)) { |
541 | $primaryvalue = array_unique(is_array($primaryvalue) ? $primaryvalue : explode(',', $primaryvalue)); | 541 | $primaryvalue = array_unique(is_array($primaryvalue) ? $primaryvalue : explode(',', $primaryvalue)); |
542 | - $primaryvalue = implode(',', array_map([$this->model->getConnection(), 'quote'], $primaryvalue)); | ||
543 | - | ||
544 | - $datalist = $this->model->where($where) | ||
545 | - ->orderRaw("FIELD(`{$primarykey}`, {$primaryvalue})") | ||
546 | - ->page($page, $pagesize) | ||
547 | - ->field($this->selectpageFields) | ||
548 | - ->select(); | 542 | + $primaryvalue = implode(',', $primaryvalue); |
543 | + | ||
544 | + $this->model->orderRaw("FIELD(`{$primarykey}`, {$primaryvalue})"); | ||
549 | } else { | 545 | } else { |
550 | - $datalist = $this->model->where($where) | ||
551 | - ->order($order) | ||
552 | - ->page($page, $pagesize) | ||
553 | - ->field($this->selectpageFields) | ||
554 | - ->select(); | 546 | + $this->model->order($order); |
555 | } | 547 | } |
556 | 548 | ||
549 | + $datalist = $this->model->where($where) | ||
550 | + ->page($page, $pagesize) | ||
551 | + ->field($this->selectpageFields) | ||
552 | + ->select(); | ||
553 | + | ||
557 | foreach ($datalist as $index => $item) { | 554 | foreach ($datalist as $index => $item) { |
558 | unset($item['password'], $item['salt']); | 555 | unset($item['password'], $item['salt']); |
559 | if ($this->selectpageFields == '*') { | 556 | if ($this->selectpageFields == '*') { |
@@ -57,7 +57,7 @@ | @@ -57,7 +57,7 @@ | ||
57 | <p style="color:#adb9e0;line-height:30px;">网站(Website)是指在因特网上根据一定的规则,使用HTML(标准通用标记语言)等工具制作的用于展示特定内容相关网页的集合。简单地说,网站是一种沟通工具,人们可以通过网站来发布自己想要公开的资讯,或者利用网站来提供相关的网络服务。</p> | 57 | <p style="color:#adb9e0;line-height:30px;">网站(Website)是指在因特网上根据一定的规则,使用HTML(标准通用标记语言)等工具制作的用于展示特定内容相关网页的集合。简单地说,网站是一种沟通工具,人们可以通过网站来发布自己想要公开的资讯,或者利用网站来提供相关的网络服务。</p> |
58 | 58 | ||
59 | <div> | 59 | <div> |
60 | - <a href="{:url('index/user/index')}" class="btn bg-primary btn-xl btn-round-lg">会员中心</a> | 60 | + <a href="{:url('index/user/index')}" class="btn bg-primary btn-xl btn-round-lg">{:__('Member center')}</a> |
61 | </div> | 61 | </div> |
62 | </div> | 62 | </div> |
63 | </div> | 63 | </div> |
@@ -26,7 +26,8 @@ | @@ -26,7 +26,8 @@ | ||
26 | "nelexa/zip": "^3.3", | 26 | "nelexa/zip": "^3.3", |
27 | "symfony/var-exporter": "^4.4.13", | 27 | "symfony/var-exporter": "^4.4.13", |
28 | "ext-json": "*", | 28 | "ext-json": "*", |
29 | - "ext-curl": "*" | 29 | + "ext-curl": "*", |
30 | + "ext-pdo": "*" | ||
30 | }, | 31 | }, |
31 | "config": { | 32 | "config": { |
32 | "preferred-install": "dist" | 33 | "preferred-install": "dist" |
-
请 注册 或 登录 后发表评论