commit | author | age
|
90c639
|
1 |
[TOC] |
Z |
2 |
|
|
3 |
# 禾匠商城v4 |
|
4 |
|
|
5 |
##前置条件 |
|
6 |
|
|
7 |
###开发者需要掌握的 |
|
8 |
|
|
9 |
- Linux基本命令使用、文件、进程管理、Nginx+PHP+MySQL+Redis环境配置 |
|
10 |
|
|
11 |
- PHP开发 |
|
12 |
|
|
13 |
- MySQL数据库 |
|
14 |
|
|
15 |
- Redis数据库 |
|
16 |
|
|
17 |
- <a href="https://www.yiiframework.com/doc/guide/2.0/zh-cn" target="_blank">Yii框架</a> |
|
18 |
|
|
19 |
- <a href="https://cn.vuejs.org/index.html" target="_blank">Vue</a> |
|
20 |
|
|
21 |
- <a href="https://element.eleme.cn/#/zh-CN" target="_blank">Element-UI</a> |
|
22 |
|
|
23 |
- <a href="https://getcomposer.org/doc/00-intro.md" target="_blank">Composer</a> |
|
24 |
|
|
25 |
### 运行环境 |
|
26 |
|
|
27 |
Linux+Nginx+PHP7.2+MySQL(5.6|5.7)+Redis(4|5) |
|
28 |
|
|
29 |
## 安装教程 |
|
30 |
|
|
31 |
### Git版本 |
|
32 |
|
|
33 |
1. `clone https://gitee.com/zjhj/zjhj_mall_v4.git` |
|
34 |
2. `cd zjhj_mall_v4` |
|
35 |
3. `cp config/db.example.php config db.php`,并配置相关数据库信息 |
|
36 |
4. `cd web`(可选) |
|
37 |
5. `php -S localhost:8000`(可选) |
|
38 |
6. 打开浏览器访问`http://localhost:8000`(可选) |
|
39 |
|
|
40 |
### 源代码包(开源版) |
|
41 |
|
|
42 |
1. 解压源代码到web目录,如`/www/wwwroot/zjhj_bd/` |
|
43 |
2. 浏览器访问您的站点,自动进入安装界面,填写数据库配置信息完成安装 |
|
44 |
|
|
45 |
## 配置 |
|
46 |
|
|
47 |
### 数据库配置 |
|
48 |
|
|
49 |
复制`db.example.php`到`db.php`,按相关参数配置。 |
|
50 |
|
|
51 |
### 本地化配置 |
|
52 |
|
|
53 |
- 环境变量 |
|
54 |
|
|
55 |
复制`.env.example.php`到`.env`按需配置相关选项。 |
|
56 |
|
|
57 |
在`YII_DEBUG = true`的情况下,所有错误结果将由Yii框架处理,`YII_DEBUG = false`或未配置`YII_DEBUG`的情况下,所有错误结果将统一处理,HTTP不再直接返回相关错误码,错误码在ajax下返回在`code`字段中。 |
|
58 |
|
|
59 |
- 系统配置 |
|
60 |
|
|
61 |
复制`local.example.php`到`local.php`按需配置相关选项。 |
|
62 |
|
|
63 |
## 快速上手案例 |
|
64 |
|
|
65 |
通过案例了解框架处理流程 |
|
66 |
|
|
67 |
1. 控制器 |
|
68 |
|
|
69 |
创建文件`/controllers/mall/DemoController.php` |
|
70 |
|
|
71 |
```php |
|
72 |
<?php |
|
73 |
namespace app\controllers\mall; |
|
74 |
|
|
75 |
use app\core\response\ApiCode; |
|
76 |
|
|
77 |
class DemoController extends MallController |
|
78 |
{ |
|
79 |
public function actionIndex() |
|
80 |
{ |
|
81 |
if (\Yii::$app->request->isAjax) { // ajax请求返回json数据,此处返回数组将自动转换成json |
|
82 |
return [ |
|
83 |
'code' => ApiCode::CODE_SUCCESS, |
|
84 |
'data' => [ |
|
85 |
'content' => 'hello!', |
|
86 |
], |
|
87 |
'msg' => 'any msg' |
|
88 |
|
|
89 |
]; |
|
90 |
} else { // 其他请求返回界面视图 |
|
91 |
return $this->render('index'); |
|
92 |
} |
|
93 |
} |
|
94 |
} |
|
95 |
|
|
96 |
``` |
|
97 |
|
|
98 |
2. 视图文件(界面) |
|
99 |
|
|
100 |
创建文件`/views/mall/demo/index.php` |
|
101 |
|
|
102 |
```php |
|
103 |
<div id="app" v-cloak> |
|
104 |
<div>{{content}}</div> |
|
105 |
</div> |
|
106 |
<script> |
|
107 |
new Vue({ |
|
108 |
el: '#app', |
|
109 |
data() { |
|
110 |
return { |
|
111 |
content: '' |
|
112 |
}; |
|
113 |
}, |
|
114 |
created() { |
|
115 |
this.$request({ |
|
116 |
params: { |
|
117 |
r: 'mall/demo/index' |
|
118 |
} |
|
119 |
}).then(e => { |
|
120 |
this.content = e.data.data.content; |
|
121 |
}).catch(e => { |
|
122 |
}); |
|
123 |
}, |
|
124 |
}); |
|
125 |
</script> |
|
126 |
``` |
|
127 |
|
|
128 |
3. 通过`http://网站目录/web/index.php?r=mall/demo/index`即可访问到。 |
|
129 |
|
|
130 |
##代码说明 |
|
131 |
|
|
132 |
###目录说明 |
|
133 |
``` |
|
134 |
/condif #配置文件 |
|
135 |
/controllers #控制器 |
|
136 |
/events #事件定义类 |
|
137 |
/forms #表单处理 |
|
138 |
/handlers #事件处理 |
|
139 |
/jobs #队列任务 |
|
140 |
/models #数据库表模型 |
|
141 |
/plugins #插件 |
|
142 |
/validators #自定义验证器 |
|
143 |
/views #视图文件 |
|
144 |
/web #入口文件、资源文件 |
|
145 |
``` |
|
146 |
|
|
147 |
###开发调试模式 |
|
148 |
|
|
149 |
要开启开发调试模式,可在项目根目录下创建`.env`配置文件,写入内容 |
|
150 |
|
|
151 |
```.env |
|
152 |
YII_DEBUG=true |
|
153 |
YII_ENV=dev |
|
154 |
``` |
|
155 |
|
|
156 |
###插件开发 |
|
157 |
|
|
158 |
插件与系统交互部分: |
|
159 |
|
|
160 |
- 后台 菜单、权限 |
|
161 |
|
|
162 |
- 小程序 导航菜单、底部导航、用户中心 |
|
163 |
|
|
164 |
每个插件代码放在/plugins目录下,插件格式可参照下面的demo插件,插件代码结构: |
|
165 |
|
|
166 |
``` |
|
167 |
├── Plugin.php |
|
168 |
├── assets |
|
169 |
│ └── css |
|
170 |
│ └── style.css |
|
171 |
├── controllers |
|
172 |
│ └── IndexController.php |
|
173 |
├── models |
|
174 |
│ └── DemoPost.php |
|
175 |
├── tree.txt |
|
176 |
└── views |
|
177 |
└── index |
|
178 |
└── index.php |
|
179 |
``` |
|
180 |
|
|
181 |
Plugin.php: 插件配置文件,必须,需要继承\app\plugins\Plugin。 |
|
182 |
|
|
183 |
assets: 插件静态资源文件,如css、js、图片,插件安装时将自动复制到`/web/assets/plugins/插件名`目录下,可使用`\app\helpers\PluginHelper::getPluginBaseAssetsUrl()`和`\app\helpers\PluginHelper::getPluginAssetsPath()`获取。 |
|
184 |
|
|
185 |
controllers: 插件控制器目录。 |
|
186 |
|
|
187 |
- 后台控制器需要继承`\app\plugins\Controller` |
|
188 |
|
|
189 |
- 小程序端控制器需要继承`\app\controllers\api\ApiController` |
|
190 |
|
|
191 |
models: 插件model文件,注意插件数据表对应的model也放在此文件夹下。 |
|
192 |
|
|
193 |
views: 插件视图文件。 |
|
194 |
|
|
195 |
小程序端配置:详见\app\plugins\Plugin()->getAppConfig(); |
|
196 |
|
|
197 |
## 规范化 |
|
198 |
|
|
199 |
### 开发规范 |
|
200 |
|
|
201 |
**PSR12** |
|
202 |
|
|
203 |
PHP规范要求符合PSR12的代码规范<https://laravel-china.org/docs/psr/>。 |
|
204 |
|
|
205 |
要求每个开发者给自己的代码编辑器安装规范检查工具: |
|
206 |
|
|
207 |
PHPStorm: <https://www.jianshu.com/p/b5697eb5f401> |
|
208 |
|
|
209 |
Sublime: <https://blog.csdn.net/he426100/article/details/76573038> |
|
210 |
|
|
211 |
**命名规范** |
|
212 |
|
|
213 |
数据表、字段、常量、变量、类、方法函数命名应该明确,尽量能从命名能知道其作用。 |
|
214 |
|
|
215 |
驼峰or下划线: 数据表、接口传递字段使用下划线,其它位置尽量使用驼峰。 |
|
216 |
|
|
217 |
数据表前缀: |
|
218 |
|
|
219 |
核心数据表前缀使用zjhj_bd_core_,如日志、定时任务. |
|
220 |
|
|
221 |
基础业务数据表使用zjhj_bd_xxx,如用户、商品、设置。 |
|
222 |
|
|
223 |
插件数据表使用zjhj_bd_插件_xxx。 |
|
224 |
|
|
225 |
**注释规范** |
|
226 |
|
|
227 |
函数、方法应当编写对应的注释,要求写明函数说明、传入参数类型、返回参数类型。 |
|
228 |
|
|
229 |
可参考内容[https://www.cnblogs.com/hellohell/p/5733712.html] |
|
230 |
|
|
231 |
**错误处理** |
|
232 |
|
|
233 |
客户提交数据验证错误: 返回错误信息。 |
|
234 |
|
|
235 |
系统错误:抛出异常。 |
|
236 |
|
|
237 |
抛出异常将通过日志系统记录进日志。 |
|
238 |
|
|
239 |
**数据库规范** |
|
240 |
|
|
241 |
- 明确字段是否是NOT NULL的,如果是NOT NULL,就不用设置默认值了,除非真的需要,如果是可以为NULL,请设置成NOT NULL并添加默认值。 |
|
242 |
|
|
243 |
- 表、字段 Charset 统一 `utf8mb4`,Collation 统一 `utf8mb4_general_ci`,存储引擎统一 `InnoDB`。 |
|
244 |
|
|
245 |
- 除非情况特殊,严禁使用 `TEXT` / `LONGTEXT` / `BLOB` / `LONGBLOB` 等类型。 |
|
246 |
|
|
247 |
- 每张表必须加入 `created_at(创建时间)` / `updated_at(更新时间)` 字段, `deleted_at(软删除时间)` 字段可按需添加。 字段类型统一为`TIMESTAMP`, |
|
248 |
`is_delete(是否删除,TINYINT(1)类型)`, |
|
249 |
|
|
250 |
- 类似 `is_delete` `store_id` 等常用查询的字段,且必须建 Index 索引。 |
|
251 |
|
|
252 |
- 对于存储 URL 的字段,必须采用 `VARCHAR` 类型,建议长度:`2048` - `8192`,参见:<https://stackoverflow.com/questions/2659952/maximum-length-of-http-get-request> |
|
253 |
|
|
254 |
|
|
255 |
**GIT规范** |
|
256 |
|
|
257 |
commit备注禁止出现`1`、`提交`等不明其意的备注! |
|
258 |
|
|
259 |
目前基础功能开发提交至dev分支,后期开发各个模块、插件的功能使用各自分支,要求分支命名能明其意,保持将dev分支合并到自己分支的习惯(每天至少一次)。 |
|
260 |
|
|
261 |
不提交的文件应该加入.gitignore,避免误提交。 |
|
262 |
|
|
263 |
------ |
|
264 |
|
|
265 |
### 安全 |
|
266 |
|
|
267 |
代码安全: SQL注入 | XSS | CSRF |
|
268 |
|
|
269 |
逻辑安全: 支付 |
|
270 |
|
|
271 |
### 目录规范化 |
|
272 |
``` |
|
273 |
. |
|
274 |
├── config // 配置文件 |
|
275 |
├── controllers // 系统控制器 |
|
276 |
│ ├── admin // 管理员(独立版管理员) |
|
277 |
│ ├── mall // 商城管理 |
|
278 |
│ └── api // 小程序接口 |
|
279 |
├── core // 系统文件 |
|
280 |
├── helpers // 公共函数、助手类 |
|
281 |
├── models // 系统模型 |
|
282 |
├── plugins // 插件 |
|
283 |
│ └── demo // 示例插件 |
|
284 |
│ ├── assets // 插件静态文件(css、js) |
|
285 |
│ ├── controllers // 插件控制器 |
|
286 |
│ ├── models // 插件模型 |
|
287 |
│ └── views // 插件视图 |
|
288 |
├── runtime // 运行临时目录 |
|
289 |
│ ├── HTML |
|
290 |
│ ├── URI |
|
291 |
│ ├── cache |
|
292 |
│ ├── debug |
|
293 |
│ ├── gii-2.0.15.1 |
|
294 |
│ └── logs |
|
295 |
├── validators // 公共验证器 |
|
296 |
├── vendor |
|
297 |
├── views // 系统视图 |
|
298 |
│ ├── error |
|
299 |
│ ├── layouts |
|
300 |
│ └── site |
|
301 |
└── web |
|
302 |
└── assets |
|
303 |
└── plugins |
|
304 |
``` |
|
305 |
|
|
306 |
------ |
|
307 |
|
|
308 |
### 公共方法/助手类 |
|
309 |
|
|
310 |
公共函数放在/helpers/functions.php, 有公共方法可以补充到这里,或是在helpers下创建自己的助手类。 |
|
311 |
|
|
312 |
### 本地化配置 |
|
313 |
|
|
314 |
**/.env** |
|
315 |
|
|
316 |
主要存储简单的环境配置,如调试模式开关,不应放敏感信息的配置。 |
|
317 |
|
|
318 |
**/config/local.php** |
|
319 |
|
|
320 |
存储系统敏感配置信息,如缓存配置、session配置。 |
|
321 |
|
|
322 |
### 错误处理 |
|
323 |
|
|
324 |
统一由/core/ErrorHandler处理,要求区分json和html的返回结果,错误信息保存进日志。 |
|
325 |
|
|
326 |
### 日志系统 |
|
327 |
|
|
328 |
日志级别 |
|
329 |
|
|
330 |
Error: 系统出错无法继续运行,如抛出Exception。 |
|
331 |
|
|
332 |
Warning: 警告,系统继续运行,只是某些结果可能跟预期不符合;场景举例:订单支付模板消息通知,模板消息没法发送成功,可记录警告信息。 |
|
333 |
|
|
334 |
Info: 普通信息,不影响系统运行;场景举例:管理员操作日志,如商品删除、订单删除、订单价格修改等操作。 |
|
335 |
|
|
336 |
统一系统日志接口 |
|
337 |
|
|
338 |
api::info(); |
|
339 |
api::warning(); |
|
340 |
api::error(); |
|
341 |
api::add( ,level); |
|
342 |
|
|
343 |
api::delete(id); |
|
344 |
api::list(page, pageSize); |
|
345 |
api::detail(id); |
|
346 |
|
|
347 |
### 返回结果 |
|
348 |
|
|
349 |
JSON数据返回结果统一以下结构 |
|
350 |
```json |
|
351 |
{ |
|
352 |
"code": 0, |
|
353 |
"msg": "操作结果。", |
|
354 |
"data": 1, |
|
355 |
"error": null |
|
356 |
} |
|
357 |
``` |
|
358 |
|
|
359 |
参数|值|类型|说明 |
|
360 |
---|---|---|--- |
|
361 |
|code|-1|integer|用户未登录| |
|
362 |
|code|0|integer|成功| |
|
363 |
|code|1|integer|失败| |
|
364 |
|code|500|integer|系统错误| |
|
365 |
|msg|-|string|-| |
|
366 |
|data|-|-|返回的数据| |
|
367 |
|error|-|-|-| |
|
368 |
|
|
369 |
### 前端开发 |
|
370 |
|
|
371 |
前端开发的成员请先熟悉ES6新特性<http://es6.ruanyifeng.com/>, 优先阅读: |
|
372 |
|
|
373 |
- 24.编程风格 |
|
374 |
|
|
375 |
- 2.let 和 const命令 |
|
376 |
|
|
377 |
- 7.函数的扩展-5.箭头函数 |
|
378 |
|
|
379 |
- 14.Promise 对象 |
|
380 |
|
|
381 |
前后端数据分离, 管理后台前端使用Vue | Element-ui | Axios, 使用示例见/controllers/DemoController。 |
|
382 |
|
|
383 |
## Yii扩展组件 |
|
384 |
|
|
385 |
### 队列服务 |
|
386 |
|
|
387 |
用于下单单线程处理、定时任务、异步任务。 |
|
388 |
|
|
389 |
详细用法见:<a href="https://github.com/yiisoft/yii2-queue/blob/master/docs/guide/usage.md#usage" target="_blank">https://github.com/yiisoft/yii2-queue/blob/master/docs/guide/usage.md#usage</a> |
|
390 |
|
|
391 |
**队列服务启动** |
|
392 |
|
|
393 |
- 【方法一】一次运行,关闭控制台会自动结束。 |
|
394 |
|
|
395 |
运行`代码目录/yii queue/listen 1` 即可。 |
|
396 |
|
|
397 |
- 【方法二】自动后台运行并创建检测服务。 |
|
398 |
|
|
399 |
运行`chmod +x 代码目录/queue.sh && 代码目录/queue.sh` 即可。 |
|
400 |
|
|
401 |
此脚本会在系统crontab创建任务每分钟检测服务是否运行,不运行会自动启动。 |
|
402 |
|
|
403 |
### 支付 |
|
404 |
|
|
405 |
支付组件封装了微信支付和余额支付的功能。 |
|
406 |
|
|
407 |
调用组件`\Yii::$app->payment` |
|
408 |
|
|
409 |
组件接口 |
|
410 |
|
|
411 |
创建待支付订单 |
|
412 |
```php |
|
413 |
$order = new \app\core\payment\PaymentOrder([ |
|
414 |
'title' => '商品名称(128)', |
|
415 |
'amount' => 100.00, //订单金额(0.01~100000000.00) |
|
416 |
'orderNo' => '订单号(32)', |
|
417 |
'notifyClass' => MyNotifyClass::class, //支付结果通知类,需继承\app\core\payment\PaymentNotify并实现notify方法 |
|
418 |
'supportPayTypes' => [ //选填,支持的支付方式,若不填将支持所有支付方式。 |
|
419 |
\app\core\payment\Payment::PAY_TYPE_HUODAO, // 货到付款 |
|
420 |
\app\core\payment\Payment::PAY_TYPE_BALANCE, // 余额 |
|
421 |
\app\core\payment\Payment::PAY_TYPE_WECHAT, // 微信支付 |
|
422 |
\app\core\payment\Payment::PAY_TYPE_ALIPAY, // 支付宝支付 |
|
423 |
\app\core\payment\Payment::PAY_TYPE_BAIDU, // 百度支付 |
|
424 |
\app\core\payment\Payment::PAY_TYPE_TOUTIAO, // 抖音头条支付 |
|
425 |
], |
|
426 |
]); |
|
427 |
$id = \Yii::$app->payment->createOrder($order); |
|
428 |
``` |
|
429 |
|
|
430 |
获取待支付订单id后可将id返回给小程序端,由小程序端的支付组件完成后续付款操作。 |
|
431 |
|
|
432 |
### 货币 |
|
433 |
目前收录了 指定用户余额、积分(添加、减少、查询、退还) |
|
434 |
指定用户添加余额 |
|
435 |
```php |
|
436 |
\Yii::$app->currency->setUser(\app\models\User)->balance->add($price, $desc, $customDesc); |
|
437 |
``` |
|
438 |
指定用户减少余额 |
|
439 |
```php |
|
440 |
\Yii::$app->currency->setUser(\app\models\User)->balance->sub($price, $desc, $customDesc); |
|
441 |
``` |
|
442 |
指定用户查询余额 |
|
443 |
```php |
|
444 |
\Yii::$app->currency->setUser(\app\models\User)->balance->select(); |
|
445 |
``` |
|
446 |
指定用户退还余额 |
|
447 |
```php |
|
448 |
\Yii::$app->currency->setUser(\app\models\User)->balance->refund($price, $desc, $customDesc); |
|
449 |
``` |
|
450 |
指定用户添加积分 |
|
451 |
```php |
|
452 |
\Yii::$app->currency->setUser(\app\models\User)->integral->add($integral, $desc, $customDesc); |
|
453 |
``` |
|
454 |
指定用户减少积分 |
|
455 |
```php |
|
456 |
\Yii::$app->currency->setUser(\app\models\User)->integral->sub($integral, $desc, $customDesc); |
|
457 |
``` |
|
458 |
指定用户查询可用积分 |
|
459 |
```php |
|
460 |
\Yii::$app->currency->setUser(\app\models\User)->integral->select(); |
|
461 |
``` |
|
462 |
指定用户查询总积分 |
|
463 |
```php |
|
464 |
\Yii::$app->currency->setUser(\app\models\User)->integral->selectTotal(); |
|
465 |
``` |
|
466 |
指定用户退还积分 |
|
467 |
```php |
|
468 |
\Yii::$app->currency->setUser(\app\models\User)->integral->refund($price, $desc, $customDesc); |
|
469 |
``` |
|
470 |
指定用户添加佣金 |
|
471 |
```php |
|
472 |
\Yii::$app->currency->setUser(\app\models\User)->brokerage->add($price, $desc, $customDesc); |
|
473 |
``` |
|
474 |
指定用户减少佣金 |
|
475 |
```php |
|
476 |
\Yii::$app->currency->setUser(\app\models\User)->brokerage->sub($price, $desc, $customDesc); |
|
477 |
``` |
|
478 |
指定用户查询可用佣金 |
|
479 |
```php |
|
480 |
\Yii::$app->currency->setUser(\app\models\User)->brokerage->select(); |
|
481 |
``` |
|
482 |
指定用户查询总佣金 |
|
483 |
```php |
|
484 |
\Yii::$app->currency->setUser(\app\models\User)->brokerage->selectTotal(); |
|
485 |
``` |
|
486 |
指定用户退还佣金 |
|
487 |
```php |
|
488 |
\Yii::$app->currency->setUser(\app\models\User)->brokerage->refund($price, $desc, $customDesc); |
|
489 |
``` |
|
490 |
|
|
491 |
## 事件 |
|
492 |
|
|
493 |
系统中一些关键步骤会触发事件,可在应用启动时挂载一些事件处理器处理相关的事件。 |
|
494 |
|
|
495 |
### 挂载处理器 |
|
496 |
|
|
497 |
创建处理器`handlers\\MyHandler`: |
|
498 |
|
|
499 |
```php |
|
500 |
<?php |
|
501 |
namespace app\handlers; |
|
502 |
|
|
503 |
|
|
504 |
class MyHandler extends HandlerBase |
|
505 |
{ |
|
506 |
|
|
507 |
/** |
|
508 |
* 事件处理注册 |
|
509 |
*/ |
|
510 |
public function register() |
|
511 |
{ |
|
512 |
\Yii::$app->on(\app\models\User::EVENT_REGISTER, function ($event) { |
|
513 |
// todo 事件相应处理 |
|
514 |
}); |
|
515 |
} |
|
516 |
} |
|
517 |
|
|
518 |
``` |
|
519 |
|
|
520 |
挂载处理器,编辑文件`handlers/HandlerRegister.php`, 在`getHandlers`加入自己的处理器类即可: |
|
521 |
```php |
|
522 |
public function getHandlers() |
|
523 |
{ |
|
524 |
return [ |
|
525 |
OrderCreatedHandler::class, |
|
526 |
MyHandler::class, |
|
527 |
]; |
|
528 |
} |
|
529 |
``` |
|
530 |
|
|
531 |
### 商城事件列表 |
|
532 |
|
|
533 |
除了框架的事件外,商城运行过程也会触发事件。 |
|
534 |
|
|
535 |
#### 用户 |
|
536 |
|
|
537 |
| 事件 | 事件类 | 事件说明 | |
|
538 |
| ------ | ------ | ------ | |
|
539 |
| app\models\User::EVENT_REGISTER | app\events\UserEvent | 小程序新用户加入后触发 | |
|
540 |
| app\models\User::EVENT_LOGIN | app\events\UserEvent | 小程序用户登录获取access_token时触发 | |
|
541 |
|
|
542 |
|
|
543 |
#### 订单 |
|
544 |
|
|
545 |
| 事件 | 事件类 | 事件说明 | |
|
546 |
| ------ | ------ | ------ | |
|
547 |
| app\models\Order::EVENT_CREATED | app\events\OrderEvent | 创建新订单后触发 | |
|
548 |
| app\models\Order::EVENT_PAYED | app\events\OrderEvent | 订单支付后触发 | |
|
549 |
| app\models\Order::EVENT_SENT | app\events\OrderEvent | 订单发货后触发 | |
|
550 |
| app\models\Order::EVENT_CONFIRMED | app\events\OrderEvent | 订单确认收货后触发 | |
|
551 |
| app\models\Order::EVENT_SALES | app\events\OrderEvent | 订单过售后触发 | |
|
552 |
| app\models\OrderRefund::EVENT_REFUND | app\events\OrderRefundEvent | 订单商品售后处理完成后触发 | |
|
553 |
|
|
554 |
**注:售后订单处理完成后需要添加售后队列** |
|
555 |
|
|
556 |
```php |
|
557 |
// 判断queue队列中的售后是否已经触发 |
|
558 |
$queueId = app\models\CoreQueueData:select(app\models\Order $order->token); |
|
559 |
if (!\Yii::$app->queue->isDone($queueId)) { |
|
560 |
// 若未触发 |
|
561 |
return ; |
|
562 |
} else { |
|
563 |
// 若已触发,则重新添加 |
|
564 |
$id = \Yii::$app->queue->delay(0)->push(new OrderSalesJob([ |
|
565 |
'orderId' => app\models\Order $order->id |
|
566 |
])); |
|
567 |
CoreQueueData::add($id, $event->order->token); |
|
568 |
} |
|
569 |
``` |
|
570 |
#### 订单支付完成事件对外开放 |
|
571 |
商城订单支付完成事件需要执行的操作都收录在\app\handlers\orderHandler\OrderPayedHandlerClass中 |
|
572 |
插件可以通过Plugin下面的getOrderHandler方法进行重载商城订单支付完成事件 |
|
573 |
订单支付完成事件处理需要继承\app\handles\orderHandler\BaseOrderPayedHandler |
|
574 |
|
|
575 |
## 前端(后台页面) |
|
576 |
|
|
577 |
### 页面规范 |
|
578 |
|
|
579 |
#### 列表 |
|
580 |
|
|
581 |
详见示例r=mall/demo/index |
|
582 |
|
|
583 |
0. 使用el-card组件,头部左侧标题,右侧添加按钮(或其他操作)。 |
|
584 |
|
|
585 |
0. 列表上边搜索表单(如果有),从左到右摆列。 |
|
586 |
|
|
587 |
0. 列表列数数据项不宜超过6列,数据项过多尽量放在同一个单元格内,用换行方式显示。 |
|
588 |
|
|
589 |
0. 对于可预知长度的列,尽量设定合适的宽度。 |
|
590 |
|
|
591 |
0. 列表数据加载过程请使用element-ui的loading动画。 |
|
592 |
|
|
593 |
0. 列表底部左侧放批量操作按钮(如果有)。 |
|
594 |
|
|
595 |
0. 列表底部右侧放分页组件。 |
|
596 |
|
|
597 |
0. el-card组件不要显示阴影。 |
|
598 |
|
|
599 |
0. 按钮的大小、颜色、样式请参照demo。 |
|
600 |
|
|
601 |
#### 表单 |
|
602 |
|
|
603 |
详见示例r=mall/demo/edit |
|
604 |
|
|
605 |
0. 待定 |
|
606 |
|
|
607 |
####新增分页获取用法 |
|
608 |
示例: |
|
609 |
`\app\models\Goods::find()->page($pagination, $limit, $page)->all();` |
|
610 |
使用page()方法可以直接获取分页列表;其中$pagination为null|\app\core\Pagination对象 |
|
611 |
|
|
612 |
### 网络 |
|
613 |
|
|
614 |
公共布局文件已经定义了全局的request实例(Axios),直接调用即可。 |
|
615 |
|
|
616 |
在vue下建议使用`this.$request`调用 |
|
617 |
|
|
618 |
- GET请求 |
|
619 |
|
|
620 |
```javascript |
|
621 |
this.$request({ |
|
622 |
method: 'get', // 默认 |
|
623 |
params: { // GET请求参数 |
|
624 |
r: 'demo/index', |
|
625 |
id: 100, |
|
626 |
}, |
|
627 |
}).then(response => { |
|
628 |
// 请求成功 |
|
629 |
// 返回的数据 |
|
630 |
console.log(response.data); |
|
631 |
}).catch(error => { |
|
632 |
// 请求出错 |
|
633 |
}); |
|
634 |
``` |
|
635 |
|
|
636 |
- POST请求 |
|
637 |
|
|
638 |
```javascript |
|
639 |
this.$request({ |
|
640 |
method: 'post', // 默认 |
|
641 |
params: { // GET请求参数 |
|
642 |
r: 'demo/index', |
|
643 |
id: 100, |
|
644 |
}, |
|
645 |
data: { // POST提交内容,数据默认统一使用Qs组件转换成QueryString |
|
646 |
title: 'hello', |
|
647 |
content: 'longtext content', |
|
648 |
}, |
|
649 |
}).then(response => { |
|
650 |
// 请求成功 |
|
651 |
// 返回的数据 |
|
652 |
console.log(response.data); |
|
653 |
}).catch(error => { |
|
654 |
// 请求出错 |
|
655 |
}); |
|
656 |
``` |
|
657 |
|
|
658 |
### 链接跳转 |
|
659 |
|
|
660 |
在Vue内可使用`this.$navigate(params, newWindow)`跳转网址: |
|
661 |
|
|
662 |
```html |
|
663 |
<el-button @click="$navigate({r: 'demo/index'})">在当前页面打开</el-button> |
|
664 |
<el-button @click="$navigate({r: 'demo/index'}, true)">在新页面打开</el-button> |
|
665 |
``` |
|
666 |
|
|
667 |
```javascript |
|
668 |
// 在当前页面打开 |
|
669 |
this.$navigate({ |
|
670 |
r: 'demo/index', |
|
671 |
id: 1, |
|
672 |
}); |
|
673 |
|
|
674 |
// 在新页面打开 |
|
675 |
this.$navigate({ |
|
676 |
r: 'demo/index', |
|
677 |
id: 1, |
|
678 |
}, true); |
|
679 |
``` |
|
680 |
|
|
681 |
其它可使用navigateTo跳转链接 |
|
682 |
|
|
683 |
```javascript |
|
684 |
navigateTo({ |
|
685 |
r: 'demo/index', |
|
686 |
id: 123 |
|
687 |
}); |
|
688 |
``` |
|
689 |
|
|
690 |
### 获取浏览器地址栏参数 |
|
691 |
|
|
692 |
链接跳转js内可使用navigateTo跳转链接 |
|
693 |
```javascript |
|
694 |
getQuery('name'); |
|
695 |
``` |
|
696 |
|
|
697 |
### 公共组件 |
|
698 |
|
|
699 |
#### 基础选择器 |
|
700 |
|
|
701 |
基础的选择器组件,用法: |
|
702 |
|
|
703 |
```html |
|
704 |
<app-picker :multiple="true" :max="2" :list="[{}, {}, {}]" @change="pickerChange"></app-picker> |
|
705 |
``` |
|
706 |
|
|
707 |
参数: |
|
708 |
|
|
709 |
- multiple: true|false, 是否可多选文件 |
|
710 |
- max: number, 多选文件上限 |
|
711 |
|
|
712 |
事件: |
|
713 |
|
|
714 |
- change: 文件选择完成,点击确认,selected(list); |
|
715 |
|
|
716 |
#### 附件选择器 |
|
717 |
|
|
718 |
可选择图片、视频等附件,或是上传新附件,用法: |
|
719 |
|
|
720 |
```html |
|
721 |
<app-attachment :multiple="true" :max="2" @selected="attachmentSelected">选择文件</app-attachment> |
|
722 |
``` |
|
723 |
|
|
724 |
参数: |
|
725 |
|
|
726 |
- multiple: true|false, 是否可多选文件 |
|
727 |
- max: number, 多选文件上限 |
|
728 |
- type: string, 文件类型,支持image|video|doc, 默认image |
|
729 |
- simple: true|false, 简约模式,只上传图片不加载图片库,适用于独立版管理部分 |
|
730 |
|
|
731 |
事件: |
|
732 |
|
|
733 |
- selected: 文件选择完成,点击确认,selected(list); |
|
734 |
|
|
735 |
#### 图片列表 |
|
736 |
|
|
737 |
用于展示单张或多张图片,用法 |
|
738 |
|
|
739 |
```html |
|
740 |
<app-gallery :show-delete="true" @deleted="picDeleted" :list="[]"></app-gallery> |
|
741 |
``` |
|
742 |
|
|
743 |
参数: |
|
744 |
|
|
745 |
- show-delete: true|false, 是否显示删除按钮 |
|
746 |
- list: Array, 图片列表,要求格式[ {url: 'http://xxx', ...}, {url: 'http://xxx', ...} ] |
|
747 |
- url: String 单图图片地址,(当传入url参数时,list参数失效) |
|
748 |
事件: |
|
749 |
|
|
750 |
- deleted: 点击删除操作,deleted(item, index); // item: 被删除元素, index: 被删元素位置 |
|
751 |
|
|
752 |
#### 导航链接列表 |
|
753 |
|
|
754 |
可选择跳转链接、底部导航链接,用法: |
|
755 |
|
|
756 |
```html |
|
757 |
<app-pick-link @selected="selectAdvertUrl"><el-button size="mini">选择链接</el-button></app-pick-link> |
|
758 |
``` |
|
759 |
|
|
760 |
事件: |
|
761 |
|
|
762 |
- selected: 链接选择完成,点击确认,selected(list); |
|
763 |
|
|
764 |
- type single(默认)|单选, multiple|多选 |
|
765 |
|
|
766 |
#### 图片显示 |
|
767 |
|
|
768 |
```html |
|
769 |
<app-image mode="" width="50px" height="50px" src="http://aaa.com/test.jpg"></app-image> |
|
770 |
``` |
|
771 |
|
|
772 |
参数: |
|
773 |
|
|
774 |
- mode: string, 图片显示方式,支持aspectFill(默认,图片自动裁剪),scaleToFill(不裁剪,自动拉伸)。 |
|
775 |
|
|
776 |
- width: string, 图片宽度,默认50px。 |
|
777 |
|
|
778 |
- radius: string, 图片圆角,默认0% |
|
779 |
|
|
780 |
- height: string, 图片高度,默认50px。 |
|
781 |
|
|
782 |
- src: string, 图片地址。 |
|
783 |
|
|
784 |
#### 自动省略号文本 |
|
785 |
|
|
786 |
```html |
|
787 |
<app-ellipsis :line="1">文本内容</app-ellipsis> |
|
788 |
``` |
|
789 |
|
|
790 |
参数: |
|
791 |
|
|
792 |
- line: number, 文本行数,当文本超过这一数值将自动显示为省略号。 |
|
793 |
|
|
794 |
#### 地图展示 |
|
795 |
|
|
796 |
可搜索位置、获取经纬度,用法: |
|
797 |
|
|
798 |
```html |
|
799 |
<app-map @map-submit="mapEvent"><el-button size="mini">展开地图</el-button></app-map> |
|
800 |
``` |
|
801 |
|
|
802 |
事件: |
|
803 |
|
|
804 |
- map-submit: 坐标选择完成,点击确认,mapEvent(e); |
|
805 |
|
|
806 |
#### 省市区选择器 |
|
807 |
|
|
808 |
```html |
|
809 |
<app-district :level="3" :detail="[]" @selected="selectDistrict" :edit="[]"></app-district> |
|
810 |
``` |
|
811 |
|
|
812 |
参数: |
|
813 |
|
|
814 |
- level: number 展示省市区的级数 3--展示省市区 2--展示省市 1--展示省 |
|
815 |
- detail: array 所有已选择的省市区 |
|
816 |
- edit: array 选中的省市区 |
|
817 |
|
|
818 |
事件: |
|
819 |
|
|
820 |
- selected: 勾选时触发selected(list) |
|
821 |
|
|
822 |
#### 商品编辑 |
|
823 |
|
|
824 |
```html |
|
825 |
<app-goods></app-goods> |
|
826 |
``` |
|
827 |
|
|
828 |
参数: |
|
829 |
- is_info: 基本信息显示状态 0--不显示 1--显示可编辑 2--显示不可编辑 |
|
830 |
- in_attr:规格及库存状态 0--不显示 1--显示可编辑 |
|
831 |
- is_goods:商品设置状态: 0--不显示 1--显示可编辑 |
|
832 |
- is_marketing:营销设置状态: 0--不显示 1--显示可编辑 |
|
833 |
- is_detail:商品详情状态: 0--不显示 1--显示可编辑 |
|
834 |
- is_share:分销设置状态: 0--不显示 1--显示可编辑 |
|
835 |
- is_member:会员设置状态: 0--不显示 1--显示可编辑 |
|
836 |
- url:表单提交地址 默认:'mall/goods/edit' |
|
837 |
- referrer:表单保存之后返回地址 默认:'mall/goods/index' |
|
838 |
- form:动态表单数据,数据结构同form表单 |
|
839 |
(如需添加额外的规格属性(积分等))```form: {extra:{first:{name:'积分',value:''}}}``` |
|
840 |
- rule:动态表单验证规则,数据数据接口同form表单验证 |
|
841 |
|
|
842 |
内部方法: |
|
843 |
- getDetail(id) 获取指定商品ID的商品信息 |
|
844 |
- getCats() 获取所有分类 |
|
845 |
- getServices() 获取商品服务 |
|
846 |
- getCards() 获取卡券列表 |
|
847 |
- getMembers() 获取会员列表 |
|
848 |
- getFreight() 获取会费规则 |
|
849 |
- getShareSetting() 获取分销设置 |
|
850 |
|
|
851 |
#### 文本编辑器 |
|
852 |
|
|
853 |
文本编辑器支持数据双向绑定(v-model)。 |
|
854 |
|
|
855 |
```php |
|
856 |
// 加载组件 |
|
857 |
Yii::$app->loadViewComponent('app-rich-text') |
|
858 |
``` |
|
859 |
|
|
860 |
```html |
|
861 |
<app-rich-text v-model="content"></app-rich-text> |
|
862 |
``` |
|
863 |
|
|
864 |
#### 热区选择 |
|
865 |
|
|
866 |
```php |
|
867 |
// 加载组件 |
|
868 |
Yii::$app->loadViewComponent('app-hotspot') |
|
869 |
``` |
|
870 |
|
|
871 |
```html |
|
872 |
<app-hotspot @confirm></app-hotspot> |
|
873 |
``` |
|
874 |
参数: |
|
875 |
- multiple:Boolean 是否多选 |
|
876 |
- pic_url:图片的链接 String |
|
877 |
- width:图片宽度 String |
|
878 |
- height:图片高度 String |
|
879 |
- hotspotArray:热区数组 Array |
|
880 |
- is_link:是否选择链接 Boolean |
|
881 |
事件: |
|
882 |
- confirm 热区选择事件 参数:热区的集合 |
|
883 |
|
|
884 |
#### 弹窗选择组件 |
|
885 |
|
|
886 |
```php |
|
887 |
// 加载组件 |
|
888 |
Yii::$app->loadViewComponent('app-dialog-select') |
|
889 |
``` |
|
890 |
|
|
891 |
```html |
|
892 |
<app-dialog-select @selected></app-dialog-select> |
|
893 |
``` |
|
894 |
参数: |
|
895 |
- url:请求链接 String |
|
896 |
- multiple:是否多选 Boolean |
|
897 |
- title: 弹框标题 |
|
898 |
事件: |
|
899 |
- selected 选择的数据 当multiple为false时参数为对象,当multiple为true时参数为对象数组 |
|
900 |
|
|
901 |
## 模板消息 |
|
902 |
发送统一调用\app\forms\common\template\TemplateSend; |
|
903 |
参数说明: |
|
904 |
- $user: 模板消息接受者的\app\models\User对象||对象数组 单发模板消息时为对象,群发模板消息时为对象数组 |
|
905 |
- $templateTpl: 需要发送的模板消息的标示,例如订单支付标示--order_pay_tpl |
|
906 |
- $templateId: 需要发送的模板消息ID 仅限群发这种直接获取template_id的,其他需要查询数据库的都不可传次参数 |
|
907 |
- $page: 小程序跳转页面 |
|
908 |
- $data: 模板消息数据 |
|
909 |
|
|
910 |
## 其它 |
|
911 |
|
|
912 |
### mall_setting字段说明 |
|
913 |
|
|
914 |
在后台管理代码 /models/Mall.php 有具体说明 |