Small program order list reconstruction solution
I. Page address of each Business Order List (History)
Business module | address | Buried point |
---|---|---|
home | /daojia/pages/order/orderList | |
Spell group | /pintuan/pages/order/orderList | |
Big electricity | /shopping/pages/order/orderList | |
counters | /shopping/pages/offlineOrder/offlineOrderList | |
Life service | /deptstore/pages/mall/order/order | |
take-out | /deptstore/pages/catering/redirect/redirect? type=caterOrder | |
Self-service billing (electronic receipt) | /selfcashiers/pages/ticket/ticketList | |
Goods loan | /rent/index/index? type=rent&page=home/order | |
The significance of burying points lies in:
Although the new order list is online, there is still a place to jump to the old page address of the order list corresponding to the business in this huge project, so it is necessary to bury the point, observe after a period of time, if there is no flow in, you can delete the old order list page;
Or re-jump to a new order list page from within the old pages, but this is not recommended, because useless code should be deleted, not kept.
Ii. Order List Merge and Reconstruction Scheme (New)
The directory structure
/order # Order submodule root directory
├─ Behaviors **# Module ** │ ├─ daojiabehavior.js # ├─ Daojiabehavior.js # │ ├─ ├─navigationHeader │ ├─ Components **# Component modules ** │ ├─navigationHeader │ │ ├─ Components **# Component modules ** │ ├─navigationHeader │ ├─orderBatchModal │ ├─panelCard │ ├─ templates **# Order card module ** │ carParking. WXML # pic.wxml # Picture card │ │ │ ├─ ├─ ├─ ├─ Constants **# Constant module ** │ ├─ ├─ ├─ Class ii │ ├─ Images **# ├─ Objects **# # Order.js │ ├─images **# # OrderHandler. Js ├ ─ pages module * * * * # page │ ├ ─ orderList │ ├ ─ orderSearch │ └ ─ refundList └ ─ utils * * # * * format. The tool module WXSCopy the code
Requirements describe
The content of this demand is generally summarized: merge the order lists of more than 10 business types of orders in Rainbow.
Let me list the materials and difficulties available at the front end:
- A total interface after the combination of all business orders, can switch different business types according to different business types, order type input parameters;
- Interface documents under different operation buttons of different services are not perfect, and they are explored by themselves (gateway paths of different formats are inconsistent and input parameters are different).
- Each operation interaction effect is not unified, lack of perfect UI material library support, explore by yourself, small program part of the business also involves H5 page embedded, very difficult;
Write the ideas
My general idea is to fix the code that doesn’t change, and for extensibility, the functional code that changes needs to be configurable.
UI templating — panelCard
In order to avoid single component code because of cumbersome logical judgment, resulting in the file code writing too long, it is necessary to separate different styles from the template template:
// panelCard.wxml
<import src="./templates/picText.wxml"/>
<import src="./templates/pic.wxml"/>
<import src="./templates/carParking.wxml" />
<import src="./templates/proText.wxml" />
<view class="body">
<template wx:if="{{order.cardType === 'picArticle' && order.itemList.length == 1}}" is="picText" data="{{... order.itemList[0]}}" />
<template wx:if="{{order.cardType === 'picArticle' && order.itemList.length > 1}}" is="pic" data="{{order}}" />
<template wx:if="{{order.cardType === 'parking'}}" is="carParking" data="{{order}}" />
<template wx:if="{{order.cardType === 'product'}}" is="proText" data="{{order}}" />
</view>
Copy the code
Unified operation portals – panelCard
All order action buttons come from this DOM node:
// panelCard.wxml
<view
class="btnItem {{format.isOperateRed(btn.btnCode) ? 'btnItemRed' : ''}}"
wx:for="{{order.operatorBtnList}}"
wx:key="index"
wx:for-item="btn"
bindtap="operate"
data-btn-code="{{btn.btnCode}}"
data-btn-name="{{btn.btnName}}"
>{{btn.btnName}}</view>
</view>
Copy the code
Let’s look at the logical code corresponding to the component, which is only responsible for forwarding the corresponding order data. All subsequent modifications basically do not need to be modified here:
// panelCard.js
/* * Operation button group */
operate(e) {
const { btnCode, btnName } = e.currentTarget.dataset
const { orderType } = this.data.order
trackEvent('orderListClick', {
buttonName: btnName,
})
// Determine the format type
const orderTypeName = ORDER_TYPE[orderType]
// Determine the operation method
const handlerFun = ORDER_OPERATOR[btnCode]
// Execute the operation request
orderHandler[handlerFun].call(this, orderTypeName, this.data.order)
}
Copy the code
Operation button behavior — orderHandler
frompanelCard
The component view layer comes in, depending on the different action buttonsbtnCode
Values in/constants/order.js
The mapping method name is found in the filehandlerFun
And then throughorderHandler
The module requests the processing function under the corresponding operation button to forward the current order type and order data;
All of the function name configuration descriptions can be found in Chinese with constants/order.js, here is a brief list of function modules:
// orderHandler.js
module.exports = {
appointCheck,
buyAgain,
cancelOrder,
cancelApply,
cancelRefundApply,
confirmMeal,
confirmReceive,
contactShop,
customerService,
delayReceive,
deleteOrder,
deleteRefundOrder,
goExpressDetail,
goOrderDetail,
goRefundOrderDetail,
goServiceComment,
goStorePage,
inviteFriend,
modifyAddress,
pay,
rentBack,
rentGet,
revokeOrder,
showCheckCode,
}
Copy the code
Configure the interface & operation input parameter — handler.js
This is the most critical file for this reconstruction. Here, the UI interaction behavior of operation buttons in different formats, interface request input parameters and request interface in different formats are configured in a UNIFIED JSON file format. First, a simple document is used to describe the purpose of parameters in the configuration file:
// Button interface & parameter configuration
// Configure parsing instructions
interface IRequestModel {
type: 'fetch' | 'link' | 'modal'; 'Make a request' | 'Link jump' | 'Two-dimensional code popover'
host: api.mpHost; Requests the gatewaypath: xxxx; Request interface addressurl: xxxx; Small program internal jump page addresscallback: IRequestModel; The callback operation after a secondary request to the interfacefields: ['fieldA'.'fieldB'. ] ; Request parameters to get the value of the corresponding key name from the list ORDERfields: [{from: 'product', which indicates that the item ID is required and needs to be obtained from the itemListisCustom: true, indicating that key is the key name and val is the corresponding valuekey: 'fieldA'Is the key nameval: 'orderFieldA', if isCustomer:falseValue from the list order; Otherwise, the default value is}.... ] }Copy the code
For example:
-
Fetch (initiating interface request and responding operation) : The operation performance of shopping and offline department stores in canceling the application:
// Cancel the application revokeOrder: { shopping: { type: 'fetch'.host: api.mpHost, path: 'xxxxx'.fields: ['orderNo'] {orderNo: order['orderNo']} }, offline: { type: 'fetch'.host: api.mpHost, path: 'yyyyy'.fields: ['orderNo']}},Copy the code
-
Link (jump page) : Shopping, offline and Group are checking logistics operation performance:
// Check the logistics
goExpressDetail: {
shopping: {
type: 'link'.url: 'xxxxx'.fields: [ // Make up the url entry:? Order_id =order['orderId']
{
key: 'order_id'.val: 'orderId'}},offline: {
type: 'link'.url: 'yyyyyy'.fields: [{key: 'orderNo'.val: 'orderNo'}},group: {
type: 'link'.url: 'zzzzz'.fields: [{key: 'orderNo'.val: 'orderNo'}}}]Copy the code
Reduce generic event redundancy — hehaviors
The side effect of mixin scheme injection is that the function name will be overwritten, but the advantage is that the amount of code to write is greatly reduced (once written, introduced and used for many times). Considering this requirement, I think we should make trade-offs for the consideration of subsequent code maintenance and new function iteration:
- Event export
// /behaviors/index.js
const cancelBehavior = require('./cancelBehavior');
const commonBehavior = require('./commonBehavior');
const daojiaBehavior = require('./daojiaBehavior');
const payBehavior = require('./payBehavior');
const zujieBehavior = require('./zujieBehavior');
module.exports = {
cancelBehavior,
commonBehavior,
daojiaBehavior,
payBehavior,
zujieBehavior,
}
Copy the code
- Events to introduce
// orderlist.js (orderSearch -- refundList -- refundList)
const { cancelBehavior, payBehavior, daojiaBehavior, zujieBehavior, commonBehavior } = require('.. /.. /behaviors/index');
Page({
// Insert all behavior methods into the Page object, because there are too many interactions involved. If you put all behavior methods into the Page object, you can't read the file.
behaviors: [
cancelBehavior,
payBehavior,
daojiaBehavior,
zujieBehavior,
commonBehavior
]
})
Copy the code
3. The concluding
Refactor the code is a very painful process, how the seemingly several unrelated business and the lack of perfect material support, do not miss, code coverage, actually test is very important, in this case, the test may not testers “dot dot” this kind of making a fool of test, but under the condition of perfect test case, After completing the reconstruction, I need to think about how to reduce the testing workload and improve the accuracy of the functional code by implementing end-to-end test case coverage similar to E2E.
Here is a small advertisement, this is my Github address, welcome to continue to follow: github.com/csonchen