shMethod.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. <!--
  2. 用途:配送方式配置页面
  3. 谁用:供货商管理员
  4. 解决什么问题:配置送货、自取、跑腿、快递、物流等配送方式的起送条件、计费规则、说明项等。
  5. -->
  6. <template>
  7. <view class="sh-method-page app-content">
  8. <!-- 顶部 Tab 切换 -->
  9. <view class="tab-bar">
  10. <view
  11. v-for="(tab, index) in tabs"
  12. :key="index"
  13. class="tab-item"
  14. :class="{ active: tabIndex === index }"
  15. @click="changeTab(index)"
  16. >
  17. {{ tab.name }}
  18. </view>
  19. </view>
  20. <!-- 配置表单区域 -->
  21. <scroll-view scroll-y class="form-scroll">
  22. <view class="form-container">
  23. <!-- 别名 -->
  24. <tui-list-cell class="line-cell" :hover="false">
  25. <view class="tui-title">别名</view>
  26. <input type="text" v-model="form.alias" class="tui-input" placeholder="请填写别名" />
  27. </tui-list-cell>
  28. <!-- 状态 -->
  29. <tui-list-cell class="line-cell" :hover="false">
  30. <view class="tui-title">状态</view>
  31. <view class="btn-group">
  32. <button
  33. class="admin-button-com middle"
  34. :class="[form.status == 1 ? 'blue' : 'default']"
  35. @click="form.status = 1"
  36. >
  37. 启用
  38. </button>
  39. <button
  40. class="admin-button-com middle"
  41. :class="[form.status == 0 ? 'blue' : 'default']"
  42. @click="form.status = 0"
  43. style="margin-left: 20upx;"
  44. >
  45. 禁用
  46. </button>
  47. </view>
  48. </tui-list-cell>
  49. <!-- 顺序 -->
  50. <tui-list-cell class="line-cell" :hover="false">
  51. <view class="tui-title">顺序</view>
  52. <input type="number" v-model="form.sort" class="tui-input" placeholder="请填写顺序" />
  53. </tui-list-cell>
  54. <!-- 送货 / 快递 特有字段 -->
  55. <block v-if="tabIndex === 0 || tabIndex === 3">
  56. <tui-list-cell class="line-cell" :hover="false">
  57. <view class="tui-title">最低消费金额</view>
  58. <input type="digit" v-model="form.minAmount" class="tui-input" placeholder="不限制填0" />
  59. </tui-list-cell>
  60. <tui-list-cell class="line-cell" :hover="false">
  61. <view class="tui-title">最低消费数量</view>
  62. <input type="number" v-model="form.minNum" class="tui-input" placeholder="不限制填0" />
  63. </tui-list-cell>
  64. <tui-list-cell class="line-cell" :hover="false">
  65. <view class="tui-title">不满条件</view>
  66. <view class="btn-group">
  67. <button
  68. class="admin-button-com middle"
  69. :class="[form.unMeet == 0 ? 'blue' : 'default']"
  70. @click="form.unMeet = 0"
  71. >
  72. 收运费
  73. </button>
  74. <button
  75. class="admin-button-com middle"
  76. :class="[form.unMeet == 2 ? 'blue' : 'default']"
  77. @click="form.unMeet = 2"
  78. style="margin-left: 10upx;"
  79. >
  80. 收包装费
  81. </button>
  82. <button
  83. class="admin-button-com middle"
  84. :class="[form.unMeet == 1 ? 'blue' : 'default']"
  85. @click="form.unMeet = 1"
  86. style="margin-left: 10upx;"
  87. >
  88. 不能买
  89. </button>
  90. </view>
  91. </tui-list-cell>
  92. <tui-list-cell class="line-cell" :hover="false" v-if="form.unMeet != 1">
  93. <view class="tui-title">{{ form.unMeet == 2 ? '包装费' : '运费' }}</view>
  94. <input type="digit" v-model="form.unMeetFee" class="tui-input" placeholder="请填写金额" />
  95. </tui-list-cell>
  96. </block>
  97. <!-- 跑腿 特有字段 -->
  98. <block v-if="tabIndex === 2">
  99. <!-- 满减规则 -->
  100. <view class="section-header">
  101. <text class="section-title">满减规则</text>
  102. <button class="admin-button-com mini blue" @click="addReduceRule">添加</button>
  103. </view>
  104. <view class="rule-list" v-if="form.reduceRules && form.reduceRules.length > 0">
  105. <view class="rule-card" v-for="(rule, index) in form.reduceRules" :key="index">
  106. <view class="rule-row">
  107. <text class="rule-label">需</text>
  108. <input type="number" v-model="rule.meetNum" class="rule-input" placeholder="0" />
  109. <text class="rule-label">扎,且</text>
  110. <input type="digit" v-model="rule.meetAmount" class="rule-input-large" placeholder="0.00" />
  111. <text class="rule-label">元,</text>
  112. <input type="digit" v-model="rule.freeKm" class="rule-input-large" placeholder="0" />
  113. <text class="rule-label">公里内免跑腿费</text>
  114. </view>
  115. <button class="admin-button-com mini default rule-del-btn" @click="removeReduceRule(index)">
  116. 删除
  117. </button>
  118. </view>
  119. </view>
  120. <view class="no-data-tip" v-else>暂无满减规则</view>
  121. <view class="notice-text">
  122. 不符合满减规则时,将通过跑腿计算运费,跑腿无法使用时,将使用自定义计费
  123. </view>
  124. <!-- 自定义计费 -->
  125. <view class="section-header">
  126. <text class="section-title">自定义计费</text>
  127. </view>
  128. <tui-list-cell class="line-cell" :hover="false">
  129. <view class="tui-title">起步价</view>
  130. <view class="input-row">
  131. <input type="digit" v-model="form.startKm" class="tui-input-sm" placeholder="0" />
  132. <text class="unit-text">km内</text>
  133. <input type="digit" v-model="form.startPrice" class="tui-input-sm" placeholder="0.00" />
  134. <text class="unit-text">元</text>
  135. </view>
  136. </tui-list-cell>
  137. <tui-list-cell class="line-cell" :hover="false">
  138. <view class="tui-title">超出起步</view>
  139. <view class="input-row">
  140. <text class="unit-text">每公里加</text>
  141. <input type="digit" v-model="form.perKmPrice" class="tui-input-sm" placeholder="0.00" />
  142. <text class="unit-text">元</text>
  143. </view>
  144. </tui-list-cell>
  145. <tui-list-cell class="line-cell" :hover="false">
  146. <view class="tui-title">临时涨价</view>
  147. <view class="input-row">
  148. <input type="digit" v-model="form.changeRate" class="tui-input-sm" placeholder="0" />
  149. <text class="unit-text">%</text>
  150. </view>
  151. </tui-list-cell>
  152. </block>
  153. <!-- 物流 特有字段 -->
  154. <block v-if="tabIndex === 4">
  155. <tui-list-cell class="line-cell" :hover="false">
  156. <view class="tui-title">配送物流</view>
  157. <button class="admin-button-com middle blue" @click="manageWl">添加 / 管理</button>
  158. </tui-list-cell>
  159. </block>
  160. <!-- 说明项区域圈起来 -->
  161. <view class="explain-section-wrapper">
  162. <view class="section-header no-margin">
  163. <text class="section-title">说明</text>
  164. <button class="admin-button-com mini blue" @click="addExplain">添加</button>
  165. </view>
  166. <view class="explain-list" v-if="form.explains && form.explains.length > 0">
  167. <view class="explain-card" v-for="(exp, index) in form.explains" :key="index">
  168. <textarea
  169. v-model="exp.explain"
  170. class="explain-textarea"
  171. placeholder="最多50字"
  172. maxlength="50"
  173. :class="[
  174. exp.color == 2 ? 'text-red' : '',
  175. exp.color == 3 ? 'text-blue' : '',
  176. exp.fontWeight == 2 ? 'text-bold' : ''
  177. ]"
  178. />
  179. <view class="explain-actions">
  180. <view class="action-group">
  181. <button
  182. class="admin-button-com mini"
  183. :class="[exp.color == 1 ? 'blue' : 'default']"
  184. @click="setExplainColor(index, 1)"
  185. >
  186. 黑色
  187. </button>
  188. <button
  189. class="admin-button-com mini"
  190. :class="[exp.color == 2 ? 'blue' : 'default']"
  191. @click="setExplainColor(index, 2)"
  192. style="margin-left: 10upx;"
  193. >
  194. 红色
  195. </button>
  196. <button
  197. class="admin-button-com mini"
  198. :class="[exp.color == 3 ? 'blue' : 'default']"
  199. @click="setExplainColor(index, 3)"
  200. style="margin-left: 10upx;"
  201. >
  202. 蓝色
  203. </button>
  204. </view>
  205. <view class="action-group" style="margin-left: 20upx;">
  206. <button
  207. class="admin-button-com mini"
  208. :class="[exp.fontWeight == 1 ? 'blue' : 'default']"
  209. @click="setExplainWeight(index, 1)"
  210. >
  211. 常规
  212. </button>
  213. <button
  214. class="admin-button-com mini"
  215. :class="[exp.fontWeight == 2 ? 'blue' : 'default']"
  216. @click="setExplainWeight(index, 2)"
  217. style="margin-left: 10upx;"
  218. >
  219. 加粗
  220. </button>
  221. </view>
  222. <button class="admin-button-com mini default explain-del-btn" @click="removeExplain(index)">
  223. 删除
  224. </button>
  225. </view>
  226. </view>
  227. </view>
  228. <view class="no-data-tip" v-else>暂无说明项</view>
  229. </view>
  230. </view>
  231. </scroll-view>
  232. <!-- 底部保存按钮 -->
  233. <view class="footer-btn-wrap">
  234. <button class="admin-button-com big blue" @click="submitSave">保存</button>
  235. </view>
  236. </view>
  237. </template>
  238. <script>
  239. import TuiListCell from "@/components/plugin/list-cell";
  240. import { getShMethodConfig, saveShMethodConfig } from "@/api/sh-method";
  241. export default {
  242. name: "shMethod",
  243. components: {
  244. TuiListCell
  245. },
  246. data() {
  247. return {
  248. tabs: [
  249. { name: "送货", value: 0 },
  250. { name: "自取", value: 1 },
  251. { name: "跑腿", value: 2 },
  252. { name: "快递", value: 3 },
  253. { name: "物流", value: 4 }
  254. ],
  255. tabIndex: 0,
  256. form: {
  257. id: 0,
  258. style: 0,
  259. alias: "",
  260. status: 1,
  261. sort: 0,
  262. minAmount: 0.00,
  263. minNum: 0,
  264. unMeet: 0,
  265. unMeetFee: 0.00,
  266. startKm: 0.00,
  267. startPrice: 0.00,
  268. perKmPrice: 0.00,
  269. changeRate: 0.00,
  270. explains: [],
  271. reduceRules: []
  272. }
  273. };
  274. },
  275. onLoad() {
  276. this.loadConfig(0);
  277. },
  278. methods: {
  279. /**
  280. * 切换 Tab
  281. * @param {number} index - 选中的 Tab 索引
  282. */
  283. changeTab(index) {
  284. if (this.tabIndex === index) return;
  285. this.tabIndex = index;
  286. this.loadConfig(index);
  287. },
  288. /**
  289. * 加载当前配送方式配置
  290. * @param {number} style - 配送类型 (0-4)
  291. */
  292. loadConfig(style) {
  293. uni.showLoading({ title: "加载中" });
  294. getShMethodConfig({ style })
  295. .then(res => {
  296. uni.hideLoading();
  297. if (res.code == 1 && res.data) {
  298. const data = res.data;
  299. this.form = {
  300. id: data.id || 0,
  301. style: style,
  302. alias: data.alias || "",
  303. status: data.status != null ? Number(data.status) : 1,
  304. sort: data.sort != null ? Number(data.sort) : 0,
  305. minAmount: data.minAmount != null ? parseFloat(data.minAmount) : 0.00,
  306. minNum: data.minNum != null ? Number(data.minNum) : 0,
  307. unMeet: data.unMeet != null ? Number(data.unMeet) : 0,
  308. unMeetFee: data.unMeetFee != null ? parseFloat(data.unMeetFee) : 0.00,
  309. startKm: data.startKm != null ? parseFloat(data.startKm) : 0.00,
  310. startPrice: data.startPrice != null ? parseFloat(data.startPrice) : 0.00,
  311. perKmPrice: data.perKmPrice != null ? parseFloat(data.perKmPrice) : 0.00,
  312. changeRate: data.changeRate != null ? parseFloat(data.changeRate) : 0.00,
  313. explains: (data.explains || []).map(exp => ({
  314. ...exp,
  315. color: exp.color != null ? Number(exp.color) : 1,
  316. fontWeight: exp.fontWeight != null ? Number(exp.fontWeight) : 1
  317. })),
  318. reduceRules: data.reduceRules || []
  319. };
  320. } else {
  321. this.$msg(res.msg || "加载失败");
  322. }
  323. })
  324. .catch(err => {
  325. uni.hideLoading();
  326. this.$msg("加载失败,请重试");
  327. });
  328. },
  329. /**
  330. * 添加满减规则
  331. */
  332. addReduceRule() {
  333. this.form.reduceRules.push({
  334. meetNum: 0,
  335. meetAmount: 0.00,
  336. freeKm: 0,
  337. sort: this.form.reduceRules.length
  338. });
  339. },
  340. /**
  341. * 删除满减规则
  342. * @param {number} index - 规则索引
  343. */
  344. removeReduceRule(index) {
  345. this.form.reduceRules.splice(index, 1);
  346. },
  347. /**
  348. * 添加说明项
  349. */
  350. addExplain() {
  351. this.form.explains.push({
  352. explain: "",
  353. color: 1, // 1: 黑色, 2: 红色, 3: 蓝色
  354. fontWeight: 1, // 1: 常规, 2: 加粗
  355. sort: this.form.explains.length
  356. });
  357. },
  358. /**
  359. * 删除说明项
  360. * @param {number} index - 说明索引
  361. */
  362. removeExplain(index) {
  363. this.$util.confirmModal({ content: "确认删除该说明吗?" }, () => {
  364. this.form.explains.splice(index, 1);
  365. });
  366. },
  367. /**
  368. * 设置说明项颜色
  369. * @param {number} index - 说明项索引
  370. * @param {number} color - 颜色值 (1: 黑色, 2: 红色, 3: 蓝色)
  371. */
  372. setExplainColor(index, color) {
  373. const exp = this.form.explains[index];
  374. if (exp) {
  375. exp.color = color;
  376. // 强制触发 Vue 2 数组/对象响应式更新
  377. this.$set(this.form.explains, index, { ...exp });
  378. }
  379. },
  380. /**
  381. * 设置说明项字重
  382. * @param {number} index - 说明项索引
  383. * @param {number} fontWeight - 字重值 (1: 常规, 2: 加粗)
  384. */
  385. setExplainWeight(index, fontWeight) {
  386. const exp = this.form.explains[index];
  387. if (exp) {
  388. exp.fontWeight = fontWeight;
  389. // 强制触发 Vue 2 数组/对象响应式更新
  390. this.$set(this.form.explains, index, { ...exp });
  391. }
  392. },
  393. /**
  394. * 跳转至物流管理
  395. */
  396. manageWl() {
  397. this.$util.pageTo({ url: "/admin/shop/wl" });
  398. },
  399. /**
  400. * 保存当前配置
  401. */
  402. submitSave() {
  403. if (this.$util.isEmpty(this.form.alias)) {
  404. this.$msg("请填写别名");
  405. return;
  406. }
  407. // 验证说明项内容
  408. for (let i = 0; i < this.form.explains.length; i++) {
  409. if (this.$util.isEmpty(this.form.explains[i].explain)) {
  410. this.$msg(`请填写第 ${i + 1} 条说明内容`);
  411. return;
  412. }
  413. }
  414. uni.showLoading({ title: "保存中" });
  415. saveShMethodConfig(this.form)
  416. .then(res => {
  417. uni.hideLoading();
  418. if (res.code == 1) {
  419. this.$msg("保存成功");
  420. // 重新加载配置刷新数据
  421. this.loadConfig(this.tabIndex);
  422. } else {
  423. this.$msg(res.msg || "保存失败");
  424. }
  425. })
  426. .catch(err => {
  427. uni.hideLoading();
  428. this.$msg("保存失败,请重试");
  429. });
  430. }
  431. }
  432. };
  433. </script>
  434. <style lang="scss" scoped>
  435. .sh-method-page {
  436. display: flex;
  437. flex-direction: column;
  438. height: 100vh;
  439. background-color: #f5f5f5;
  440. }
  441. /* 顶部 Tab 栏 */
  442. .tab-bar {
  443. display: flex;
  444. background-color: #ffffff;
  445. border-bottom: 1upx solid #eeeeee;
  446. position: sticky;
  447. top: 0;
  448. z-index: 10;
  449. height: 90upx;
  450. align-items: center;
  451. }
  452. .tab-item {
  453. flex: 1;
  454. text-align: center;
  455. font-size: 34upx;
  456. color: #666666;
  457. height: 90upx;
  458. line-height: 90upx;
  459. position: relative;
  460. transition: all 0.2s ease;
  461. font-weight: bold;
  462. &.active {
  463. color: #3385ff;
  464. font-weight: bold;
  465. &::after {
  466. content: "";
  467. position: absolute;
  468. bottom: 0;
  469. left: 50%;
  470. transform: translateX(-50%);
  471. width: 40upx;
  472. height: 4upx;
  473. background-color: #3385ff;
  474. border-radius: 2upx;
  475. }
  476. }
  477. }
  478. /* 表单区域 */
  479. .form-scroll {
  480. flex: 1;
  481. overflow: hidden;
  482. }
  483. .form-container {
  484. padding: 20upx 20upx 160upx 20upx;
  485. }
  486. .line-cell {
  487. background-color: #ffffff;
  488. border-radius: 12upx;
  489. margin-bottom: 20upx;
  490. }
  491. .tui-title {
  492. font-size: 28upx;
  493. color: #333333;
  494. width: 200upx;
  495. }
  496. .tui-input {
  497. flex: 1;
  498. font-size: 28upx;
  499. color: #333333;
  500. text-align: right;
  501. }
  502. .btn-group {
  503. display: flex;
  504. align-items: center;
  505. margin-left: auto;
  506. }
  507. /* 跑腿自定义计费输入行 */
  508. .input-row {
  509. display: flex;
  510. align-items: center;
  511. justify-content: flex-end;
  512. flex: 1;
  513. }
  514. .tui-input-sm {
  515. width: 120upx;
  516. height: 60upx;
  517. border: 1upx solid #dddddd;
  518. border-radius: 8upx;
  519. font-size: 26upx;
  520. text-align: center;
  521. color: #333333;
  522. background-color: #fafafa;
  523. }
  524. .unit-text {
  525. font-size: 26upx;
  526. color: #666666;
  527. margin: 0 10upx;
  528. }
  529. /* 模块标题 */
  530. .section-header {
  531. display: flex;
  532. align-items: center;
  533. justify-content: space-between;
  534. margin: 30upx 10upx 15upx 10upx;
  535. }
  536. .section-title {
  537. font-size: 30upx;
  538. font-weight: bold;
  539. color: #333333;
  540. }
  541. /* 满减规则卡片 */
  542. .rule-list {
  543. margin-bottom: 20upx;
  544. }
  545. .rule-card {
  546. background-color: #ffffff;
  547. border-radius: 12upx;
  548. padding: 20upx;
  549. margin-bottom: 20upx;
  550. border: 1upx solid #eef2f9;
  551. }
  552. .rule-row {
  553. display: flex;
  554. align-items: center;
  555. flex-wrap: wrap;
  556. font-size: 26upx;
  557. color: #333333;
  558. }
  559. .rule-label {
  560. margin: 0 8upx;
  561. }
  562. .rule-input {
  563. width: 70upx;
  564. height: 50upx;
  565. border: 1upx solid #cccccc;
  566. border-radius: 6upx;
  567. text-align: center;
  568. font-size: 24upx;
  569. background-color: #fafafa;
  570. }
  571. .rule-input-large {
  572. width: 110upx;
  573. height: 50upx;
  574. border: 1upx solid #cccccc;
  575. border-radius: 6upx;
  576. text-align: center;
  577. font-size: 24upx;
  578. background-color: #fafafa;
  579. }
  580. .rule-del-btn {
  581. margin-top: 15upx;
  582. margin-left: auto;
  583. }
  584. /* 提示文字 */
  585. .notice-text {
  586. font-size: 24upx;
  587. color: #ff6900;
  588. line-height: 36upx;
  589. padding: 15upx 20upx;
  590. background-color: #fffaf5;
  591. border-radius: 8upx;
  592. border: 1upx solid #ffe8d6;
  593. margin: 20upx 10upx;
  594. }
  595. /* 说明项区域圈起来 */
  596. .explain-section-wrapper {
  597. background-color: #ffffff;
  598. border-radius: 12upx;
  599. padding: 24upx;
  600. margin-top: 30upx;
  601. border: 1upx solid #eef2f9;
  602. box-shadow: 0 2upx 8upx rgba(0, 0, 0, 0.02);
  603. }
  604. .no-margin {
  605. margin-top: 0 !important;
  606. margin-left: 0 !important;
  607. margin-right: 0 !important;
  608. margin-bottom: 20upx !important;
  609. }
  610. /* 说明卡片 */
  611. .explain-list {
  612. margin-bottom: 20upx;
  613. }
  614. .explain-card {
  615. background-color: #ffffff;
  616. border-radius: 12upx;
  617. padding: 20upx;
  618. margin-bottom: 20upx;
  619. border: 1upx solid #eef2f9;
  620. }
  621. .explain-textarea {
  622. width: 100%;
  623. height: 120upx;
  624. font-size: 30upx;
  625. color: #333333;
  626. background-color: #fafafa;
  627. border: 1upx solid #eeeeee;
  628. border-radius: 8upx;
  629. padding: 15upx;
  630. box-sizing: border-box;
  631. margin-bottom: 15upx;
  632. }
  633. .explain-actions {
  634. display: flex;
  635. align-items: center;
  636. justify-content: space-between;
  637. }
  638. .action-group {
  639. display: flex;
  640. align-items: center;
  641. }
  642. .explain-del-btn {
  643. margin-left: auto;
  644. }
  645. /* 文本样式控制 */
  646. .text-red {
  647. color: #ff3841 !important;
  648. }
  649. .text-blue {
  650. color: #3385ff !important;
  651. }
  652. .text-bold {
  653. font-weight: bold !important;
  654. }
  655. .no-data-tip {
  656. font-size: 26upx;
  657. color: #999999;
  658. text-align: center;
  659. padding: 40upx 0;
  660. }
  661. /* 底部保存按钮 */
  662. .footer-btn-wrap {
  663. position: fixed;
  664. bottom: 0;
  665. left: 0;
  666. right: 0;
  667. background-color: #ffffff;
  668. padding: 20upx 30upx;
  669. border-top: 1upx solid #eeeeee;
  670. z-index: 10;
  671. display: flex;
  672. justify-content: flex-end; /* 居右边 */
  673. }
  674. .footer-btn-wrap .admin-button-com.big {
  675. width: 350upx !important; /* 按钮长一些 */
  676. margin: 0 !important; /* 清除默认居中 margin */
  677. }
  678. </style>