主题
报修业务(二)
本页对应 报修业务,共 7 段视频,约 1 小时 14 分。
学习目标
- 能够调用报修列表接口获取分页数据,并结合登录状态检测、空列表提示和四种报修状态样式完成列表页渲染与验证。
- 能够通过地址参数传递并获取报修 ID,调用报修详情接口,将小区、项目、电话、时间、问题描述、附件图片及状态条件渲染到详情页。
- 能够使用小程序地图组件配置中心点、缩放级别和标记点,并借助位置服务生成路线数据,完成经纬度解压处理后在地图上展示路线。
- 能够复用新增报修接口实现修改报修功能,根据是否存在 ID 区分新增与编辑,完成表单数据回显、提交修改,并同步修正
house info相关字段。 - 能够根据报修状态仅对“受理中”显示取消按钮,调用取消报修接口传递 ID,成功后跳转回报修列表并验证状态更新。
知识点
路线规划要解决什么问题
路线规划的目标是在地图上展示两点之间的行进路线。为什么需要它?在报修详情里,只有状态为“上门中”时才需要让用户看到维修师傅从起点到终点的路线;怎么想?把任务拆成两半:小程序 map 组件负责“画地图、画标记、画线”,腾讯位置服务负责“算出一条路线上的经纬度坐标”;怎么做?先用 map 渲染地图,再调用位置服务的 direction 方法拿到路线坐标,最后把坐标交给 polyline。易错点是:地图组件本身不会计算路线,polyline 也不能随便写几个点,它需要的是路线服务返回并处理后的坐标数组。
先掌握 map 组件的基本属性
为什么需要先学 map?因为路线最终要显示在地图上,地图的中心点、缩放级别、标记点都影响用户能否看到结果。怎么想?先记住五个属性:latitude、longitude 指定地图中心点;scale 指定初始缩放比例,取值范围 3–20,默认 16;markers 是标记点数组;polyline 是路线数组。怎么做?在页面数据中给出中心点经纬度和缩放级别即可。转写稿中演示过:scale 改成 3 时地图展示内容不详细,改成 20 时地图被放大、内容更详细;所以值越小缩放越小,值越大展示越细。易错点是:不要把 scale 写成超出 3–20 的值;中心点也不要随手写得太远,否则后面路线可能“画出来了但不在视野里”。
用 markers 标出起点和终点
为什么需要 markers?因为只有一条线不够直观,用户需要看到起点、终点,甚至师傅当前位置。怎么想?markers 是数组,每个标记点是一个对象;对象里必须有 id,否则会产生错误。怎么做?笔记中的示例是:
javascript
// repqir_pkg/pages/detail/index.js
Page({
data: {
markers: [
{
id: 1,
latitude: 40.22077,
longitude: 116.23128,
width: 24,
height: 30,
},
{
id: 2,
latitude: 40.225857999999995,
longitude: 116.23246699999999,
iconPath: '/static/images/marker.png',
width: 40,
height: 40,
},
],
}
})这里 iconPath 可以自定义标记图片,width/height 控制尺寸。转写稿里还提醒:iconPath 支持网络路径,也支持本地路径;本地图片要放在项目目录中并按实际路径引用。易错点:id 不能漏;两个标记点的经纬度不要离得太远,否则在某个缩放级别下可能只看到一个点;改完标记点后可以适当调整 scale 观察效果。
用 direction 计算路线坐标
为什么需要位置服务?因为两点之间的路线不是直线,而是一串连续坐标点,必须由路线规划服务计算。怎么想?调用腾讯位置服务的 direction,传入交通工具 mode、起点 from、终点 to。怎么做?笔记中的核心代码如下:
javascript
// repqir_pkg/pages/detail/index.js
Page({
data: {},
onLoad() {
// 生成路线
this.getPolyline()
},
// 调用位置服务(路线规划)
getPolyline() {
qqMap.direction({
mode: 'bicycling',
from: '40.227978,116.22998',
to: '40.22077,116.23128',
success: ({ result }) => {
const coors = result.routes[0].polyline
const points = []
//坐标解压(返回的点串坐标,通过前向差分进行压缩)
for (let i = 2; i < coors.length; i++) {
coors[i] = Number(coors[i - 2]) + Number(coors[i]) / 1000000
}
// 获取经纬度
for (let i = 0; i < coors.length; i += 2) {
points.push({ latitude: coors[i], longitude: coors[i + 1] })
}
// 渲染数据
this.setData({
latitude: points[30].latitude,
longitude: points[30].longitude,
polyline: [
{points, color: '#5591af', width: 4},
],
})
},
})
},
})转写稿中强调:from 和 to 是“经度,纬度”的字符串,中间用逗号拼接,不能有空格;result.routes[0].polyline 是压缩过的坐标串,不能直接给地图用,需要按官方公式解压;解压后还要二次遍历,因为数组是“纬度、经度、纬度、经度”交替存放,所以循环步长为 2,coors[i] 作纬度、coors[i + 1] 作经度,组装成 { latitude, longitude }。易错点:不要自己猜压缩算法;不要漏掉 Number() 转换;不要直接把 coors 塞给 polyline。
渲染 polyline 并调整地图视野
为什么还要调整中心点?因为路线算出来后,如果地图中心点还在原来的位置,可能看不到整条线。怎么想?把 latitude、longitude 改成路线上的某个点,例如示例中的 points[30],让视野落到路线附近;再把 points 交给 polyline 的 points,并设置 color、width。怎么做?polyline 是数组,每个元素可包含 points、color、width。易错点:polyline 的属性名是 points,不是 point;路线颜色和宽度只是显示配置,关键是坐标数组格式必须正确。调试时可以先 console.log(result) 看 routes[0].polyline,再打印解压后的 coors 和二次加工后的 points,确认数据从“压缩串”变成“经纬度对象数组”,最后检查地图中心点是否落在路线附近。
需求与页面复用
为什么需要:用户已经添加过报修,但报修内容可能填错,例如报修项目、联系电话、预约时间或问题描述需要调整。如果只能重新新增,会产生重复数据,也不符合真实业务。
怎么想:修改报修不一定要新建页面。添加报修和修改报修的表单结构完全一致,可以复用同一个 form 页面:有 id 时表示修改,没有 id 时表示新增。
怎么做:从报修详情页点击“修改信息”进入表单页,把报修 id 通过 URL 传过去;表单页在 onLoad 中接收 id,有 id 才查询原数据。
易错点:不要一进入表单页就无条件请求详情,否则新增报修时也会发请求;id 要从详情页已有数据中取,不要手写死。
先传 ID:从详情页进入表单页
为什么需要:修改操作必须知道“改哪一条报修”,所以 id 是修改报修的核心参数。
怎么想:详情页当前数据里已经有 repairDetail.id,点击按钮时通过事件对象把 id 带到跳转地址中;表单页再通过 onLoad({ id }) 解构出来。
怎么做:在详情页按钮事件中调用 wx.navigateTo,路径指向 repair_pkg/pages/form/index,并拼接 ?id=...。进入表单页后先打印 id,确认参数传递成功。
易错点:URL 参数名要和 onLoad 解构名一致;跳转路径不要漏掉分包目录;调试时可在 Network 或 Console 中确认 id 是否拿到。
修正字段名:houseName → houseInfo
为什么需要:接口返回的报修详情中,房屋信息字段叫 houseInfo,而之前表单里用的是 houseName。如果不统一,setData({ ...repairDetail }) 回填后,模板仍然读 houseName,报修房屋的默认值就显示不出来。
怎么想:回填数据来自接口,页面读取字段必须与接口保持一致,所以把旧字段统一改成 houseInfo。
怎么做:本节笔记明确要改 4 个位置,参考视频逐一修改:初始数据定义处、用户选择房屋后的赋值处、页面模板渲染处、控制样式时使用该数据处。
易错点:不要只改一处。漏改任意一处,都可能出现房屋名不显示、选中样式异常或提交数据不一致。转写稿中“house衣服”是口误,实际就是 houseInfo。
读取原报修数据并回填表单
为什么需要:修改前要先让用户看到原报修内容,否则用户面对空表单无法判断改了什么。
怎么想:拿到 id 后调用详情接口 /repair/:id,成功后将返回对象展开到 data 中,表单绑定的字段就会自动显示。
怎么做:保留下面代码,onLoad({ id }) 中有 id 才调用 getRepairDetail(id);接口 code === 10000 后再 setData({ ...repairDetail })。
易错点:setData 要展开对象,不能写成 this.setData({ repairDetail }),否则模板读不到顶层字段;接口失败要 return wx.utils.toast(),避免继续渲染错误数据。
javascript
// repair_pkg/pages/form/index.js
Page({
data: {},
onLoad({id}) {
// ...
// 如果有id表明是修改操作
if (id) this.getRepairDetail(id)
},
// 获取待修改的报修信息
async getRepairDetail(id) {
// 调用接口
const { code, data: repairDetail } = await wx.http.get('/repair/' + id)
// 检测是否调用成功
if (code !== 10000) return wx.utils.toast()
// 渲染数据
this.setData({ ...repairDetail })
},
})提交时携带 ID,复用新增接口
为什么需要:修改完成后要重新提交。后端新增和修改使用同一个接口,通过提交数据中是否包含 id 来区分:有 id 是修改,没有 id 是新增。
怎么想:表单回填时 id 已经进入 data,提交时把它一起解构并传给接口即可,不需要另写一套提交逻辑。
怎么做:先 validate() 校验表单,再解构 id、houseId、repairItemId、mobile、appointment、description、attachment,POST 到 /repair;成功后 redirectTo 报修列表页。
易错点:提交时忘记带 id,后端会当成新增;code !== 10000 要提示“在线报修失败!”;用 redirectTo 可关闭当前表单页,避免用户返回后重复提交。转写稿调试时也验证了:修改报修项目后重新提交,再进详情能看到新内容;同时顺带检查列表页报修项目字段是否显示正确。
javascript
// repair_pkg/pages/form/index.js
Page({
data: {},
onLoad() {},
getRepairDetail(id) {
// ...
},
async submitForm() {
// 验证表单数据
if (!this.validate()) return
// 提取接口需要的数据
const {
id, houseId, repairItemId, mobile, appointment, description, attachment
} = this.data
// 调用接口
const { code } = await wx.http.post('/repair', {
id,
houseId,
repairItemId,
mobile,
appointment,
description,
attachment,
})
// 检测接口是否调用成功
if (code !== 10000) return wx.utils.toast('在线报修失败!')
// 跳转到报修列表页面
wx.redirectTo({
url: '/repair_pkg/pages/list/index',
})
},
})调试与易错点汇总
为什么需要:修改报修同时涉及 URL 传参、字段名统一、详情回填和提交复用,任何一环出错都会表现为“数据没显示”或“改成了新增”。
怎么想:按链路排查:先看详情页跳转 URL 是否有 id,再看表单页 Console 是否拿到 id,再看 Network 中详情请求是否成功,最后看提交请求体里是否带 id。
怎么做:重点检查 4 处 houseInfo 是否全部改完;确认 setData 使用展开语法;提交前确认 this.data.id 存在;成功后到详情页或列表页确认数据已更新。
易错点:无 id 时不要查详情;字段名不要混用 houseName 和 houseInfo;详情接口失败不要继续回填;提交失败要提示;修改成功后用 redirectTo 回列表,避免回到旧表单。
功能目标与业务规则
在线报修提交后,用户可能会发现报修内容填错,或者临时不需要维修了。此时如果没有取消入口,用户只能再提交一条新报修,既容易造成数据混乱,也不符合真实业务。因此本节要实现“取消报修”:当在线报修处于“受理中”时,允许用户取消本次报修。
这里的关键不是先写按钮,而是先明确业务规则:只有报修状态为“受理中”时才允许取消。转写稿中说明,状态值 1 表示受理中;如果是“上门中”,维修师傅已经出发,就不允许取消;如果是“已完成”,也没有取消的必要。所以页面上的“取消报修”按钮不能一直显示,必须根据状态做条件渲染。
接口文档地址如下:
取消报修接口要求以 PUT 方式发起请求,路径中需要包含报修 ID。转写稿特别提醒:接口路径中的 repair 写成了 repaire,多了一个字母 e,调用时必须按文档拼写,否则接口会调用失败。返回结果中根据 code 判断是否成功即可。
界面入口与按钮显示条件
取消报修按钮位于报修详情页 repair_pkg/pages/detail/index。参考示例代码如下:
xml
<view class="toolbar">
<view
mark:id="{{repairDetail.id}}"
bind:tap="editRepair"
class="button-text active"
>修改信息</view>
<view
wx:if="{{repairDetail.status === 1}}"
mark:id="{{repairDetail.id}}"
bind:tap="cancelRepair"
class="button-text"
>取消报修</view>
</view>怎么想:按钮是否显示由 repairDetail.status === 1 控制。只有状态为 1,也就是受理中时,才渲染“取消报修”。同时通过 mark:id="{{repairDetail.id}}" 把当前报修 ID 标记到事件上,点击事件触发后就能从事件对象中取出 ID。
怎么做:在 WXML 中给“取消报修”绑定 bind:tap="cancelRepair",并用 wx:if 控制显示。易错点是不要用状态 2 或 3 来判断,也不要把按钮无条件显示;否则用户在上门中或已完成状态仍能点击,业务上不允许。
事件参数与接口调用
在详情页 JS 中新增 cancelRepair 方法。参考示例代码如下:
javascript
// repair_pkg/pages/detail/index.js
Page({
data: {},
onLoad() {},
// 取消报修
async cancelRepair(ev) {
// 调用接口
const { code } = await wx.http.put('/cancel/repaire/' + ev.mark.id)
// 检测接口是否调用成功
if (code !== 10000) return wx.utils.toast()
// 跳转到报修列表页面
wx.navigateTo({
url: '/repair_pkg/pages/list/index',
})
},
})怎么想:点击事件中先拿到 ID,再调用取消接口。ID 不是从 data 里重新查,而是通过 mark:id 传参,在事件对象中读取 ev.mark.id。接口用 wx.http.put,路径为 /cancel/repaire/ 拼接 ID。拿到返回结果后解构出 code,只有 code === 10000 才表示成功。
怎么做:如果 code !== 10000,调用 wx.utils.toast() 提示失败并 return;成功则跳转到报修列表页 /repair_pkg/pages/list/index。易错点有两个:一是路径中的 repaire 拼写不能改;二是不要忘记用 ev.mark.id 取参数,直接写 id 会拿不到。
调试验证与易错点
调试时先找一个“受理中”的报修详情,页面上应出现“取消报修”按钮;再切换到“已取消”或其他状态的报修,按钮不应出现。点击受理中的“取消报修”后,页面应跳转到报修列表,并且原报修状态变为“已取消”。转写稿中的验证过程也是这样:当前处于受理中时可以看到按钮,点击后跳转到列表页面,原本受理中的状态变成已取消,说明逻辑生效。
易错点清单:第一,状态判断必须是 repairDetail.status === 1;第二,mark:id 和 ev.mark.id 要成对使用;第三,接口路径 /cancel/repaire/ 多一个 e,不能按常规单词改成 repair;第四,成功判断是 code !== 10000;第五,成功后按笔记要求使用 wx.navigateTo 跳转到报修列表页。把这些点检查完,取消报修功能就完成了。
课件图示




代码示例
1. 路线规划:map 组件 + 腾讯位置服务
xml
<!-- repqir_pkg/pages/detail/index.wxml -->
<map
latitude="{{latitude}}"
longitude="{{longitude}}"
scale="16"
markers="{{markers}}"
polyline="{{polyline}}"
></map>javascript
// repqir_pkg/pages/detail/index.js
// 需在文件顶部按项目实际路径引入封装好的 qqMap,例如:
// import qqMap from '../../../utils/qqmap'
Page({
data: {
markers: [
{
id: 1,
latitude: 40.22077,
longitude: 116.23128,
width: 24,
height: 30,
},
{
id: 2,
latitude: 40.225857999999995,
longitude: 116.23246699999999,
iconPath: '/static/images/marker.png',
width: 40,
height: 40,
},
],
},
onLoad() {
// 生成路线
this.getPolyline()
},
// 调用位置服务(路线规划)
getPolyline() {
qqMap.direction({
mode: 'bicycling',
from: '40.227978,116.22998',
to: '40.22077,116.23128',
success: ({ result }) => {
const coors = result.routes[0].polyline
const points = []
// 坐标解压(返回的点串坐标,通过前向差分进行压缩)
for (let i = 2; i < coors.length; i++) {
coors[i] = Number(coors[i - 2]) + Number(coors[i]) / 1000000
}
// 获取经纬度
for (let i = 0; i < coors.length; i += 2) {
points.push({ latitude: coors[i], longitude: coors[i + 1] })
}
// 渲染数据
this.setData({
latitude: points[30].latitude,
longitude: points[30].longitude,
polyline: [
{ points, color: '#5591af', width: 4 },
],
})
},
})
},
})要点解释
latitude、longitude、scale控制地图中心点和缩放级别,scale取值范围是 3–20。markers中每个标记点必须写id,否则会报错;iconPath可自定义图标,width/height控制尺寸。polyline的points不能直接使用接口返回数据,必须先按官方方式解压,再二次加工成{ latitude, longitude }。- 易错点:
result.routes[0].polyline是压缩数据;points要作为polyline[0].points传入;points[30]要确保存在。
2. 修改报修:有 id 才回显,提交时带 id 区分新增/修改
javascript
// repair_pkg/pages/form/index.js
Page({
data: {},
onLoad({ id }) {
// 如果有 id 表明是修改操作
if (id) this.getRepairDetail(id)
},
// 获取待修改的报修信息
async getRepairDetail(id) {
// 调用接口
const { code, data: repairDetail } = await wx.http.get('/repair/' + id)
// 检测是否调用成功
if (code !== 10000) return wx.utils.toast()
// 渲染数据
this.setData({ ...repairDetail })
},
async submitForm() {
// 验证表单数据
if (!this.validate()) return
// 提取接口需要的数据
const {
id,
houseId,
repairItemId,
mobile,
appointment,
description,
attachment,
} = this.data
// 调用接口
const { code } = await wx.http.post('/repair', {
id,
houseId,
repairItemId,
mobile,
appointment,
description,
attachment,
})
// 检测接口是否调用成功
if (code !== 10000) return wx.utils.toast('在线报修失败!')
// 跳转到报修列表页面
wx.redirectTo({
url: '/repair_pkg/pages/list/index',
})
},
})要点解释
onLoad({ id })从 URL 参数中解构id,只有存在id时才调用getRepairDetail。this.setData({ ...repairDetail })是把详情对象展开成表单字段,不是整体赋值。- 提交时接口会通过是否包含
id区分“修改报修”和“新增报修”,所以id必须一起提交。 - 易错点:
houseName要改成houseInfo,且涉及 4 个位置,否则报修房屋默认值不会展示;validate()要先校验再提交。
3. 取消报修:仅受理中显示按钮,成功后跳列表
xml
<!-- repair_pkg/pages/detail/index.wxml -->
<view class="toolbar">
<view
mark:id="{{repairDetail.id}}"
bind:tap="editRepair"
class="button-text active"
>修改信息</view>
<view
wx:if="{{repairDetail.status === 1}}"
mark:id="{{repairDetail.id}}"
bind:tap="cancelRepair"
class="button-text"
>取消报修</view>
</view>javascript
// repair_pkg/pages/detail/index.js
Page({
data: {},
onLoad() {},
// 取消报修
async cancelRepair(ev) {
// 调用接口
const { code } = await wx.http.put('/cancel/repaire/' + ev.mark.id)
// 检测接口是否调用成功
if (code !== 10000) return wx.utils.toast()
// 跳转到报修列表页面
wx.navigateTo({
url: '/repair_pkg/pages/list/index',
})
},
})要点解释
wx:if="{{repairDetail.status === 1}}"表示只有状态为“受理中”时才显示“取消报修”按钮。mark:id="{{repairDetail.id}}"把报修 ID 通过事件对象传给方法,JS 中用ev.mark.id获取。- 取消接口使用
wx.http.put,路径是/cancel/repaire/+ ID。 - 易错点:笔记中接口路径
repaire多一个e,不能写成repair;状态字段是status;成功后再跳转报修列表。
常见错误
地图一片空白 / 控制台报 marker 相关错误
- 现象:
markers传入后地图上不出现标记点,或开发者工具报错提示缺少字段。 - 原因:某个 marker 没有写
id,或两个 marker 的经纬度完全一致导致重叠成一个点。 - 修法:每个 marker 给唯一
id;相邻标记点经纬度做微小偏移,并把scale调到能同时容纳两点的值。
- 现象:
polyline 画不出来,或画出一条横跨全国的乱线
- 现象:
polyline已 setData,地图上没有线;或线跑到完全无关的区域。 - 原因:直接把
result.routes[0].polyline交给polyline,跳过了「前向差分解压」和「两两配对成{latitude, longitude}」两步;或解压时把coors当成不可变数据处理。 - 修法:严格照官方示例,先
coors[i] = Number(coors[i-2]) + Number(coors[i])/1000000,再for (i=0; i<coors.length; i+=2)push 成对象数组。
- 现象:
路线数据正确但屏幕上什么都看不见
- 现象:Network 里坐标点正常,
polyline也有值,地图上仍是空白区域。 - 原因:地图中心点
latitude/longitude还是写死的北京坐标,而路线在别处。 - 修法:把中心点改成路线上的某个点(如
points[0]或points[30]),让视野落到路线附近。
- 现象:Network 里坐标点正常,
修改报修时房屋名称不回显
- 现象:进入编辑页,小区/房屋一栏是空的,其它字段正常。
- 原因:
houseName→houseInfo只改了部分位置(初始data、选房赋值、wxml 渲染、样式判断共 4 处),接口返回的是houseInfo。 - 修法:全局搜索
houseName逐个替换,改完用「详情 → 修改」走一遍确认回显。
点「提交」后列表多出一条新记录,原记录没变
- 现象:编辑保存成功,但变成新增。
- 原因:提交时没把
id一起传给接口,后端按「无 id = 新增」处理。 - 修法:解构参数时带上
id,随wx.http.post('/repair', {...})一并提交;同时确认onLoad({id})里if (id)才调getRepairDetail,否则新增页会被旧数据污染。
取消报修按钮到处都在,或点了 404
- 现象:已完成/已上门的单子也能点「取消报修」;或点击后接口报错。
- 原因:按钮没加
wx:if="{{repairDetail.status === 1}}";或路径按「正确拼写」写成了/cancel/repair/,而接口文档里是repaire。 - 修法:按钮加状态条件;路径以文档为准逐字符比对,不要凭记忆拼。
列表页没数据时白屏,无任何提示
- 现象:接口返回空数组,页面什么都不显示。
- 原因:
isEmpty未初始化,或 wxml 里条件取反写反(该显示提示时显示了列表)。 - 修法:
data里给isEmpty: false初值,请求后按rows.length === 0赋值,wxml 用wx:if/wx:else二选一,注意取反方向。
练习
在不看笔记的情况下,写出
map组件同时展示 2 个 marker + 1 条 polyline 所需的最小data结构与 wxml 片段,并说明scale取 3 与取 20 时画面差异的原因。封装一个纯函数
decompressToPoints(coors),输入接口原始压缩串,输出[{latitude, longitude}, ...];再用一组假数据(至少 6 个数字)手算验证前两个点,说明为什么循环步长是 2、为什么取经度要用i + 1。报修详情页新增「复制上次报修」需求:点击后跳到 form 页并预填上次内容但不带
id。请说明表单页现有代码需要怎样调整才能既支持「新增」「编辑」又支持这种「预填新增」,并指出哪一行最容易写错。给报修列表的状态做映射:
status0/1/2/3 分别对应「已取消/受理中/上门中/已完成」及不同样式类。请写出 wxml 条件写法,并说明为什么用wx:if链而不是在 JS 里算一个statusText(两种都给出,比较优劣)。取消报修成功后当前用的是
wx.navigateTo回列表。请分析这在页面栈上会造成什么问题,给出至少两种改进方案并说明各自副作用。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 享+生活-报修列表 | 12:23 |
| 2 | 享+生活-报修详情 | 11:35 |
| 3 | 享+生活-报修详情(路线规划)-1 | 08:42 |
| 4 | 享+生活-报修详情(路线规划)-2 | 19:00 |
| 5 | 享+生活-修改报修信息-1 | 06:50 |
| 6 | 享+生活-修改报修信息-2 | 08:36 |
| 7 | 享+生活-取消报修 | 06:58 |
小结
- 地图功能是「组件 + 服务」两件事:
map负责渲染,腾讯位置服务负责算坐标;两者数据格式不通用,中间必须做转换。 markers的id是硬性要求,polyline的points必须是{latitude, longitude}对象数组——这两处格式错是最高频的失败原因。- 位置服务返回的坐标是压缩的,解压 + 二次加工这两段代码属于「照抄即可」的模板,理解含义比背下来更重要:本质是把一维数组按 2 个一组还原成经纬度对。
- 路线画不出来时优先排查三件事:中心点、
scale、polyline数据结构,而不是怀疑接口。 - 新增与编辑共用一个接口和一个页面,靠「有无
id」分流;因此id的传递链(列表 → 详情 → 表单 → 提交)任何一环断掉,都会静默变成新增。 - 字段重命名(
houseName→houseInfo)属于典型的「一处漏改、全页失效」,改完必须四个位置全部核对并实测回显。 - 涉及状态的交互(取消报修)要同时做「UI 条件渲染」和「接口调用」两层控制,只做一层都会出现越权或误操作。
- 列表页的空态、状态样式、跳转传参这三类细节不写不错、一漏就白屏,交付前应把每条状态分支都手工点一遍。