SpringBoot-项目2-收货地址(新增,修改,删除,设为默认收货地址)

关于收货地址数据的功能分析

在处理收货地址数据时,需要完成的功能有:新增收货地址、显示收货地址列表、编辑收货地址、删除收货地址、将此收货地址设为默认。
以上功能的开发顺序应该是:增加 > 显示列表 > 设为默认 > 删除 > 编辑。

26. 收货地址-创建数据表

创建收货地址的数据表:

# 注意:以下没有添加相应的非空not null约束

create table t_address(
    aid int primary key auto_increment comment '收货地址id',
    uid int comment '用户id',
    name varchar(20) comment '收货人',
    province_name varchar(15) comment '省,如:浙江省',
    province_code char(6) comment '省的代号,如:330000',
    city_name varchar(15) comment '市,如:杭州市',
    city_code char(6) comment '市的代号,如:330100',
    area_name varchar(15) comment '区县,如:萧山区',
    area_code char(6) comment '区县的代号,如:330109',
    zip char(6) comment '邮政编码',
	address varchar(50) comment '详细地址',
    phone varchar(20) comment '手机',
    tel varchar(20) comment '固话',
    tag varchar(10) comment '地址类型,如:家,公司,学校等',
    is_default int(1) comment '是否默认:0-非默认,1-默认',
    created_user VARCHAR(20) COMMENT '创建人',
  	created_time DATETIME COMMENT '创建时间',
  	modified_user VARCHAR(20) COMMENT '最后修改人',
  	modified_time DATETIME COMMENT '最后修改时间'
)charset=utf8mb4;

27. 收货地址-创建实体类

cn.demo.store.entity包中创建Address 类:

/**
 * 收货地址数据的实体类
 */
public class Address extends BaseEntity {
   

  private static final long serialVersionUID = 6946915401608396201L;
  
  private Integer aid;
  private Integer uid;
  private String name;
  private String provinceName;
  private String provinceCode;
  private String cityName;
  private String cityCode;
  private String areaName;
  private String areaCode;
  private String address;
  private String zip;
  private String phone;
  private String tel;
  private String tag;
  private Integer isDefault;
 
  // 生成所有属性的SET/GET方法
  // 生成基于aid的hashCode()和equals()方法
  // 生成输出所有属性值和父类toString()的toString()方法
  
}

28. 收货地址-增加-持久层

(a) 规划需要的SQL语句

增加收货地址需要执行的是INSERT操作,向数据表中插入新的收货地址的SQL语句大致是:

INSERT INTO t_address (除了aid以外的字段列表) VALUES (匹配的值列表);

每个用户可以创建的收货地址的数量应该是有限的,收货地址数据的数量达到一定数量后,就不允许创建新的收货地址了!就需要知道某个用户当前已经创建了多少条收货地址,可以通过查询来实现:

SELECT COUNT(*) FROM t_address WHERE uid=?;

每个用户可以创建多条收货地址,但是,应该有且仅有1条是默认的收货地址,可以设置规则为“用户的第1条收货地址是默认的,后续可以另行设置”,通过以上查询也可以实现相关的判断,例如,统计的收货地址数量为0时,如果增加收货地址,则是默认收货地址,当统计的数量不是0时,则不是默认收货地址。

(b) 设计抽象方法

cn.demo.store.mapper下创建AddressMapper接口,并在接口添加所分析的2个功能的抽象方法:

/**
 * 处理收货地址数据的持久层接口
 */
public interface AddressMapper {
   

  /**
   * 插入收货地址数据
   * @param address 收货地址数据
   * @return 受影响的行数
   */
  Integer insert(Address address);

  /**
   * 统计某个用户的收货地址的数量
   * @param uid 用户的id
   * @return 该用户的收货地址的数量
   */
  Integer countByUid(Integer uid);

}

© 配置映射并测试

src/main/resources/mappers中创建得到AddressMapper.xml文件,然后在子级配置以上2个抽象方法对应的SQL语句:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="cn.demo.store.mapper.AddressMapper">

  <!-- 插入收货地址数据 -->
  <!-- Integer insert(Address address) -->
  <insert id="insert" useGeneratedKeys="true" keyProperty="aid">
    INSERT INTO t_address (
      uid, name, province_name, province_code,
      city_name, city_code, area_name, area_code,
      address, zip, phone, tel,
      tag, is_default,
      created_user, created_time, modified_user, modified_time
    ) VALUES (
      #{uid}, #{name}, #{provinceName}, #{provinceCode},
      #{cityName}, #{cityCode}, #{areaName}, #{areaCode},
      #{address}, #{zip}, #{phone}, #{tel},
      #{tag}, #{isDefault},
      #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime}
    )
  </insert>
  
  <!-- 统计某个用户的收货地址的数量 -->
  <!-- Integer countByUid(Integer uid) -->
  <select id="countByUid" resultType="java.lang.Integer">
    SELECT COUNT(*) FROM t_address WHERE uid=#{uid}
  </select>

</mapper>

src/test/java下的cn.demo.store.mapper包中创建AddressMapperTests测试类,编写并执行单元测试:

@RunWith(SpringRunner.class)
@SpringBootTest 
public class AddressMapperTests {
   
  
  @Autowired
  private AddressMapper mapper;
  
  @Test
  public void insert() {
   
    Address address = new Address();
    address.setName("小王");
    address.setUid(1);
    Integer rows = mapper.insert(address);
    System.err.println("rows=" + rows);
  }
  
  @Test
  public void countByUid() {
   
    Integer uid = 1;
    Integer count = mapper.countByUid(uid);
    System.err.println("count=" + count);
  }

}

29. 收货地址-增加-业务层

(a) 规划业务流程、业务逻辑,并创建可能出现的异常

在处理“增加收货地址”的业务时,应该先统计当前用户的收货地址数据的数量,假设每个用户最多只允许创建3条收货地址,根据统计结果与允许的最大值(3)进行判断,如果已经达到最大值标准,则不允许创建收货地址,抛出AddressSizeLimitException;如果尚未达到上限,则允许创建,当插入收货地址时,可能抛出InsertException

所以,需要确保已经存在以上2种异常类。

(b) 设计抽象方法

cn.demo.store.service包下创建AddressService接口,并添加抽象方法:

/**
 * 处理收货地址数据的业务层接口
 */
public interface AddressService {
   

  /**
   * 增加新的收货地址
   * @param uid 用户id
   * @param username 用户名
   * @param address 收货地址数据
   */
  void addnew(Integer uid, String username, Address address);
  
}

© 实现抽象方法并测试

cn.demo.store.service.impl包中创建AddressServiceImpl类,实现以上接口,在类的声明之前添加@Service注解,并在类中添加持久层对象:

/**
 * 处理收货地址数据的业务层实现类
 */
@Service
public class AddressServiceImpl implements AddressService {
   

  @Autowired
  private AddressMapper addressMapper;
  
}

在具体实现之前,可以将收货地址数量的上限值配置在application.properties中:

project.address-max-size=20

并在AddressServiceImpl中读取该配置值:

@Value("${project.address-max-size}")
private int maxSize;

关于业务方法的具体实现代码为:

  @Override
  public void addnew(Integer uid, String username, Address address) {
   
    // 基于参数uid调用addressMapper.countByUid()统计当前用户的收货地址数据的数量
    Integer count = addressMapper.countByUid(uid);
    // 判断统计结果是否达到最大值
    if (count >= maxSize) {
   
      // 是:抛出AddressSizeLimitException
      throw new AddressSizeLimitException("增加收货地址失败!您的收货地址的数量已经达到上限(" + maxSize + "条)!");
    }

    // 创建时间对象
    Date now = new Date();
    // 基于统计结果判断得到是否默认的值
    Integer isDefault = (count == 0) ? 1 : 0; 
    // 补全参数address中的属性:uid > 参数uid
    address.setUid(uid);
    // 补全参数address中的属性:is_default > 以上判断结果
    address.setIsDefault(isDefault);
    // 补全参数address中的属性:日志 > 参数username,新创建时间对象
    address.setCreatedUser(username);
    address.setCreatedTime(now);
    address.setModifiedUser(username);
    address.setModifiedTime(now);
    // 基于参数address调用addressMapper.insert()执行插入收货地址数据,并获取返回值
    Integer rows = addressMapper.insert(address);
    // 判断返回值是否不为1
    if (rows != 1) {
   
      // 是:抛出InsertException
      throw new InsertException("增加收货地址失败!插入收货地址数据时出现未知错误,请联系系统管理员!");
    }
  }

最后,在src/test/javacn.demo.store.service包中创建AddressServiceTests测试类,测试以上方法的功能:

@RunWith(SpringRunner.class)
@SpringBootTest
public class AddressServiceTests {
   
  
  @Autowired
  private AddressService service;
  
  @Test
  public void addnew() {
   
    try {
   
      Integer uid = 100;
      String username = "小赵同学";
      Address address = new Address();
      address.setName("鸣人君");
      service.addnew(uid, username, address);
      System.err.println("OK.");
    } catch (ServiceException e) {
   
      System.err.println(e.getClass().getName());
      System.err.println(e.getMessage());
    }
  }
  
}

30. 收货地址-增加-控制器层

(a) 处理新创建的异常类型

此次在处理业务时,创建了新的AddressSizeLimitException异常,需要在GlobalHandleException中添加分支进行处理。

(b) 设计需要处理的请求

  • 请求路径:/addresses/addnew
  • 请求参数:Address address, HttpSession session
  • 请求方式:POST
  • 响应数据:JsonResult

© 处理请求并测试

在很多操作中,都需要从Session中获取登录信息,获取的代码比较麻烦,所以,可以新创建一个控制器类的基类,把获取Session数据的代码封装在基类的方法中,便于各控制器调用:

abstract class BaseController {
   
  
  /**
   * 响应到客户端的、表示操作成功的状态值
   */
  protected static final int OK = 2000;
  
  protected final Integer getUidFromSession(HttpSession session) {
   
    return Integer.valueOf(session.getAttribute("uid").toString());
  }
  
  protected final String getUsernameFromSession(HttpSession session) {
   
    return session.getAttribute("username").toString();
  }
  
}

cn.demo.store.controller包中创建AddressController控制器类,继承自BaseController,在类的声明之前添加@RestController@RequestMapping("addresses")注解,并在类中声明@Autowired private AddressService addressService;业务层对象:

@RestController
@RequestMapping("addresses")
public class AddressController extends BaseController {
   
  
  @Autowired
  private AddressService addressService;
  
}

然后,在类中添加处理请求的方法:

// http://localhost:8080/addresses/addnew?name=Alex
@PostMapping("addnew")
public JsonResult<Void> addnew(Address address, HttpSession session) {
  // 从session中获取uid和username
  Integer uid = getUidFromSession(session);
  String username = getUsernameFromSession(session);
  // 调用业务对象的方法
  addressService.addnew(uid, username, address);
  // 响应成功
  return new JsonResult<>(OK);
}

完成后,在浏览器中进行测试。

31. 收货地址-增加-前端页面

<script type="text/javascript">
  $("#btn-addnew").click(function() {
   
    $.ajax({
   
      "url":"/addresses/addnew",
      "data":$("#form-addnew").serialize(),
      "type":"post",
      "dataType":"json",
      "success":function(json) {
   
        if (json.state == 2000) {
   
          alert("增加成功!");
        } else {
   
          alert(json.message);
        }
      },
      "error":function() {
   
        alert("您的登录信息已过期,请重新登录!\n\n* 以上提示,在开发过程中不要太当真,请检查浏览器的Console和Network面板!");
      }
    });
  });
</script>

32. 导入省市区数据表

下载省市区数据表的SQL脚本,登录MySQL控制台,选择需要使用的数据库,通过source 命令导入即可。

-- MySQL dump 10.14  Distrib 5.5.47-MariaDB, for Win64 (AMD64)
--
-- Host: localhost    Database: tedu_store
-- ------------------------------------------------------
-- Server version	5.5.47-MariaDB

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `t_dict_district`
--

DROP TABLE IF EXISTS `t_dict_district`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t_dict_district` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent` varchar(6) DEFAULT NULL,
  `code` varchar(6) DEFAULT NULL,
  `name` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3524 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `t_dict_district`
--

LOCK TABLES `t_dict_district` WRITE;
/*!40000 ALTER TABLE `t_dict_district` DISABLE KEYS */;
INSERT INTO `t_dict_district` VALUES (1,'110100','110101','东城区'),(2,'110100','110102','西城区'),(3,'110100','110103','崇文区'),(4,'110100','110104','宣武区'),(5,'110100','110105','朝阳区'),(6,'110100','110106','丰台区'),(7,'110100','110107','石景山区'),(8,'110100','110108','海淀区'),(9,'110100','110109','门头沟区'),(10,'110100','110111','房山区'),(11,'110100','110112','通州区'),(12,'110100','110113','顺义区'),(13,'110100','110114','昌平区'),(14,'110100','110115','大兴区'),(15,'110100','110116','怀柔区'),(16,'110100','110117','平谷区'),(17,'110200','110228','密云县'),(18,'110200','110229','延庆县'),(19,'120100','120101','和平区'),(20,'120100','120102','河东区'),(21,'120100','120103','河西区'),(22,'120100','120104','南开区'),(23,'120100','120105','河北区'),(24,'120100','120106','红桥区'),(25,'120100','120107','塘沽区'),(26,'120100','120108','汉沽区'),(27,'120100','120109','大港区'),(28,'120100','120110','东丽区'),(29,'120100','120111','西青区'),(30,'120100','120112','津南区'),(31,'120100','120113','北辰区'),(32,'120100','120114','武清区'),(33,'120100','120115','宝坻区'),(34,'120200','120221','宁河县'),(35,'120200','120223','静海县'),(36,'120200','120225','蓟 县'),(37,'130100','130101','市辖区'),(38,'130100','130102','长安区'),(39,'130100','130103','桥东区'),(40,'130100','130104','桥西区'),(41,'130100','130105','新华区'),(42,'130100','130107','井陉矿区'),(43,'130100','130108','裕华区'),(44,'130100','130121','井陉县'),(45,'130100','130123','正定县'),(46,'130100','130124','栾城县'),(47,'130100','130125','行唐县'),(48,'130100','130126','灵寿县'),(49,'130100','130127','高邑县'),(50,'130100','130128','深泽县'),(51,'130100','130129','赞皇县'),(52,'130100','130130','无极县'),(53,'130100','130131','平山县'),(54,'130100','130132','元氏县'),(55,'130100','130133','赵 县'),(56,'130100','130181','辛集市'),(57,'130100','130182','藁城市'),(58,'130100','130183','晋州市'),(59,'130100','130184','新乐市'),(60,'130100','130185','鹿泉市'),(61,'130200','130201','市辖区'),(62,'130200','130202','路南区'),(63,'130200','130203','路北区'),(64,'130200','130204','古冶区'),(65,'130200','130205','开平区'),(66,'130200','130207','丰南区'),(67,'130200','130208','丰润区'),(68,'130200','130223','滦 县'),(69,'130200','130224','滦南县'),(70,'130200','130225','乐亭县'),(71,'130200','130227','迁西县'),(72,'130200','130229','玉田县'),(73,'130200','130230','唐海县'),(74,'130200','130281','遵化市'),(75,'130200','130283','迁安市'),(76,'130300','130301','市辖区'),(77,'130300','130302','海港区'),(78,'130300','130303','山海关区'),(79,'130300','130304','北戴河区'),(80,'130300','130321','青龙满族自治县'),(81,'130300','130322','昌黎县'),(82,'130300','130323','抚宁县'),(83,'130300','130324','卢龙县'),(84,'130400','130401','市辖区'),(85,'130400','130402','邯山区'),(86,'130400','130403','丛台区'),(87,'130400','130404','复兴区'),(88,'130400','130406','峰峰矿区'),(89,'130400','130421','邯郸县'),(90,'130400','130423','临漳县'),(91,'130400','130424','成安县'),(92,'130400','130425','大名县'),(93,'130400','130426','涉 县'),(94,'130400','130427','磁 县'),(95,'130400','130428','肥乡县'),(96,'130400','130429','永年县'),(97,'130400','130430','邱 县'),(98,'130400','130431','鸡泽县'),(99,'130400','130432','广平县'),(100,'130400','130433','馆陶县'),(101,'130400','130434','魏 县'),(102,'130400','130435','曲周县'),(103,'130400','130481','武安市'),(104,'130500','130501','市辖区'),(105,'130500','130502','桥东区'),(106,'130500','130503','桥西区'),(107,'130500','130521','邢台县'),(108,'130500','130522','临城县'),(109,'130500','130523','内丘县'),(110,'130500','130524','柏乡县'),(111,'130500','130525','隆尧县'),(112,'130500','130526','任 县'),(113,'130500','130527','南和县'),(114,'130500','130528','宁晋县'),(115,'130500','130529','巨鹿县'),(116,'130500','130530','新河县'),(117,'130500','130531','广宗县'),(118,'130500','130532','平乡县'),(119,'130500','130533','威 县'),(120,'130500','130534','清河县'),(121,'130500','130535','临西县'),(122,'130500','130581','南宫市'),(123,'130500','130582','沙河市'),(124,'130600','130601','市辖区'),(125,'130600','130602','新市区'),(126,'130600','130603','北市区'),(127,'130600','130604','南市区'),(128,'130600','130621','满城县'),(129,'130600','130622','清苑县'),(130,'130600','130623','涞水县'),(131,'130600','130624','阜平县'),(132,'130600','130625','徐水县'),(133,'130600','130626','定兴县'),(134,'130600','130627','唐 县'),(135,'130600','130628','高阳县'),(136,'130600','130629','容城县'),(137,'130600','130630','涞源县'),(138,'130600','130631','望都县'),(139,'130600','130632','安新县'),(140,'130600','130633','易 县'),(141,'130600','130634','曲阳县'),(142,'130600','130635','蠡 县'),(143,'130600','130636','顺平县'),(144,'130600','130637','博野县'),(145,'130600','130638','雄 县'),(146,'130600','130681','涿州市'),(147,'130600','130682','定州市'),(148,'130600','130683','安国市'),(149,'130600','130684','高碑店市'),(150,'130700','130701','市辖区'),(151,'130700','130702','桥东区'),(152,'130700','130703','桥西区'),(153,'130700','130705','宣化区'),(154,'130700','130706','下花园区'),(155,'130700','130721','宣化县'),(156,'130700','130722','张北县'),(157,'130700','130723','康保县'),(158,'130700','130724','沽源县'),(159,'130700','130725','尚义县'),(160,'130700','130726','蔚 县'),(161,'130700','130727','阳原县'),(162,'130700','130728','怀安县'),(163,'130700','130729','万全县'),(164,'130700','130730','怀来县'),(165,'130700','130731','涿鹿县'),(166,'130700','130732','赤城县'),(167,'130700','130733','崇礼县'),(168,'130800','130801','市辖区'),(169,'130800','130802','双桥区'),(170,'130800','130803','双滦区'),(171,'130800','130804','鹰手营子矿区'),(172,'130800','130821','承德县'),(173,'130800','130822','兴隆县'),(174,'130800','130823','平泉县'),(175,'130800','130824','滦平县'),(176,'130800','130825','隆化县'),(177,'130800','130826','丰宁满族自治县'),(178,'130800','130827','宽城满族自治县'),(179,'130800','130828','围场满族蒙古族自治县'),(180,'130900','130901','市辖区'),(181,'130900','130902','新华区'),(182,'130900','130903','运河区'),(183,'130900','130921','沧 县'),(184,'130900','130922','青 县'),(185,'130900','130923','东光县'),(186,'130900','130924','海兴县'),(187,'130900','130925','盐山县'),(188,'130900','130926','肃宁县'),(189,'130900','130927','南皮县'),(190,'130900','130928','吴桥县'),(191,'130900','130929','献 县'),(192,'130900','130930','孟村回族自治县'),(193,'130900','130981','泊头市'),(194,'130900','130982','任丘市'),(195,'130900','130983','黄骅市'),(196,'130900','130984','河间市'),(197,'131000','131001','市辖区'),(198,'131000','131002','安次区'),(199,'131000','131003','广阳区'),(200,'131000','131022','固安县'),(201,'131000','131023','永清县'),(202,'131000','131024','香河县'),(203,'131000','131025','大城县'),(204,'131000','131026','文安县'),(205,'131000','131028','大厂回族自治县'),(206,'131000','131081','霸州市'),(207,'131000','131082','三河市'),(208,'131100','131101','市辖区'),(209,'131100','131102','桃城区'),(210,'131100','131121','枣强县'),(211,'131100','131122','武邑县'),(212,'131100','131123','武强县'),(213,'131100','131124','饶阳县'),(214,'131100','131125','安平县'),(215,'131100','131126','故城县'),(216,'131100','131127','景 县'),(217,'131100','131128','阜城县'),(218,'131100','131181','冀州市'),(219,'131100','131182','深州市'),(220,'140100','140101','市辖区'),(221,'140100','140105','小店区'),(222,'140100','140106','迎泽区'),(223,'140100','140107','杏花岭区'),(224,'140100','140108','尖草坪区'),(225,'140100','140109','万柏林区'),(226,'140100','140110','晋源区'),(227,'140100','140121','清徐县'),(228,'140100','140122','阳曲县'),(229,'140100','140123','娄烦县'),(230,'140100','140181','古交市'),(231,'140200','140201','市辖区'),(232,'140200','140202','城 区'),(233,'140200','140203','矿 区'),(234,'140200','140211','南郊区'),(235,'140200','140212','新荣区'),(236,'140200','140221','阳高县'),(237,'140200','140222','天镇县'),(238,'140200','140223','广灵县'),(239,'140200','140224','灵丘县'),(240,'140200','140225','浑源县'),(241,'140200','140226','左云县'),(242,'140200','140227','大同县'),(243,'140300','140301','市辖区'),(244,'140300','140302','城 区'),(245,'140300','140303','矿 区'),(246,'140300','140311','郊 区'),(247,'140300','140321','平定县'),(248,'140300','140322','盂 县'),(249,'140400','140401','市辖区'),(250,'140400','140402','城 区'),(251,'140400','140411','郊 区'),(252,'140400','140421','长治县'),(253,'140400','140423','襄垣县'),(254,'140400','140424','屯留县'),(255,'140400','140425','平顺县'),(256,'140400','140426','黎城县'),(257,'140400','140427','壶关县'),(258,'140400','140428','长子县'),(259,'140400','140429','武乡县'),(260,'140400','140430','沁 县'),(261,'140400','140431','沁源县'),(262,'140400','140481','潞城市'),(263,'140500','140501','市辖区'),(264,'140500','140502','城 区'),(265,'140500','140521','沁水县'),(266,'140500','140522','阳城县'),(267,'140500','140524','陵川县'),(268,'140500','140525','泽州县'),(269,'140500','140581','高平市'),(270,'140600','140601','市辖区'),(271,'140600','140602','朔城区'),(272,'140600','140603','平鲁区'),(273,'140600','140621','山阴县'),(274,'140600','140622','应 县'),(275,'140600','140623','右玉县'),(276,'140600','140624','怀仁县'),(277,'140700','140701','市辖区'),(278,'140700','140702','榆次区'),(279,'140700','140721','榆社县'),(280,'140700','140722','左权县'),(281,'140700','140723','和顺县'),(282,'140700','140724','昔阳县'),(283,'140700','140725','寿阳县'),(284,'140700','140726','太谷县'),(285,'140700','140727','祁 县'),(286,'140700','140728','平遥县'),(287,'140700','140729','灵石县'),(288,'140700','140781','介休市'),(289,'140800','140801','市辖区'),(290,'140800','140802','盐湖区'),(291,'140800','140821','临猗县'),(292,'140800','140822','万荣县'),(293,'140800','140823','闻喜县'),(294,'140800','140824','稷山县'),(295,'140800','140825','新绛县'),(296,'140800','140826','绛 县'),(297,'140800','140827','垣曲县'),(298,'140800','140828','夏 县'),(299,'140800','140829','平陆县'),(300,'140800','140830','芮城县'),(301,'140800','140881','永济市'),(302,'140800','140882','河津市'),(303,'140900','140901','市辖区'),(304,'140900','140902','忻府区'),(305,'140900','140921','定襄县'),(306,'140900','140922','五台县'),(307,'140900','140923','代 县'),(308,'140900','140924','繁峙县'),(309,'140900','140925','宁武县'),(310,'140900','140926','静乐县'),(311,'140900','140927','神池县'),(312,'140900','140928','五寨县'),(313,'140900','140929','岢岚县'),(314,'140900','140930','河曲县'),(315,'140900','140931','保德县'),(316,'140900','140932','偏关县'),(317,'140900','140981','原平市'),(318,'141000','141001','市辖区'),(319,'141000','141002','尧都区'),(320,'141000','141021','曲沃县'),(321,'141000','141022','翼城县'),(322,'141000','141023','襄汾县'),(323,'141000','141024','洪洞县'),(324,'141000','141025','古 县'),(325,'141000','141026','安泽县'),(326,'141000','141027','浮山县'),(327,'141000','141028','吉 县'),(328,'141000','141029','乡宁县'),(329,'141000','141030','大宁县'),(330,'141000','141031','隰 县'),(331,'141000','141032','永和县'),(332,'141000','141033','蒲 县'),(333,'141000','141034','汾西县'),(334,'141000','141081','侯马市'),(335,'141000','141082','霍州市'),(336,'141100','141101','市辖区'),(337,'141100','141102','离石区'),(338,'141100','141121','文水县'),(339,'141100','141122','交城县'),(340,'141100','141123','兴 县'),(341,'141100','141124','临 县'),(342,'141100','141125','柳林县'),(343,'141100','141126','石楼县'),(344,'141100','141127','岚 县'),(345,'141100','141128','方山县'),(346,'141100','141129','中阳县'),(347,'141100','141130','交口县'),(348,'141100','141181','孝义市'),(349,'141100','141182','汾阳市'),(350,'150100','150101','市辖区'),(351,'150100','150102','新城区'),(352,'150100','150103','回民区'),(353,'150100','150104','玉泉区'),(354,'150100','150105','赛罕区'),(355,'150100','150121','土默特左旗'),(356,'150100','150122','托克托县'),(357,'150100','150123','和林格尔县'),(358,'150100','150124','清水河县'),(359,'150100','150125','武川县'),(360,'150200','150201','市辖区'),(361,'150200','150202','东河区'),(362,'150200','150203','昆都仑区'),(363,'150200','150204','青山区'),(364,'150200','150205','石拐区'),(365,'150200','150206','白云矿区'),(366,'150200','150207','九原区'),(367,'150200','150221','土默特右旗'),(368,'150200','150222','固阳县'),(369,'150200','150223','达尔罕茂明安联合旗'),(370,'150300','150301','市辖区'),(371,'150300','150302','海勃湾区'),(372,'150300','150303','海南区'),(373,'150300','150304','乌达区'),(374,'150400','150401','市辖区'),(375,'150400','150402','红山区'),(376,'150400','150403','元宝山区'),(377,'150400','150404','松山区'),(378,'150400','150421','阿鲁科尔沁旗'),(379,'150400','150422','巴林左旗'),(380,'150400','150423','巴林右旗'),(381,'150400','150424','林西县'),(382,'150400','150425','克什克腾旗'),(383,'150400','150426','翁牛特旗'),(384,'150400','150428','喀喇沁旗'),(385,'150400','150429','宁城县'),(386,'150400','150430','敖汉旗'),(387,'150500','150501','市辖区'),(388,'150500','150502','科尔沁区'),(389,'150500','150521','科尔沁左翼中旗'),(390,'150500','150522','科尔沁左翼后旗'),(391,'150500','150523','开鲁县'),(392,'150500','150524','库伦旗'),(393,'150500','150525','奈曼旗'),(394,'150500','150526','扎鲁特旗'),(395,'150500','150581','霍林郭勒市'),(396,'150600','150602','东胜区'),(397,'150600','150621','达拉特旗'),(398,'150600','150622','准格尔旗'),(399,'150600','150623','鄂托克前旗'),(400,'150600','150624','鄂托克旗'),(401,'150600','150625','杭锦旗'),(402,'150600','150626','乌审旗'),(403,'150600','150627','伊金霍洛旗'),(404,'150700','150701','市辖区'),(405,'150700','150702','海拉尔区'),(406,'150700','150721','阿荣旗'),(407,'150700','150722','莫力达瓦达斡尔族自治旗'),(408,'150700','150723','鄂伦春自治旗'),(409,'150700','150724','鄂温克族自治旗'),(410,'150700','150725','陈巴尔虎旗'),(411,'150700','150726','新巴尔虎左旗'),(412,'150700','150727','新巴尔虎右旗'),(413,'150700','150781','满洲里市'),(414,'150700','150782','牙克石市'),(415,'150700','150783','扎兰屯市'),(416,'150700','150784','额尔古纳市'),(417,'150700','150785','根河市'),(418,'150800','150801','市辖区'),(419,'150800','150802','临河区'),(420,'150800','150821','五原县'),(421,'150800','150822','磴口县'),(422,'150800','150823','乌拉特前旗'),(423,'150800','150824','乌拉特中旗'),(424,'150800','150825','乌拉特后旗'),(425,'150800','150826','杭锦后旗'),(426,'150900','150901','市辖区'),(427,'150900','150902','集宁区'),(428,'150900','150921','卓资县'),(429,'150900','150922','化德县'),(430,'150900','150923','商都县'),(431,'150900','150924','兴和县'),(432,'150900','150925','凉城县'),(433,'150900','150926','察哈尔右翼前旗'),(434,'150900','150927','察哈尔右翼中旗'),(435,'150900','150928','察哈尔右翼后旗'),(436,'150900','150929','四子王旗'),(437,'150900','150981','丰镇市'),(438,'152200','152201','乌兰浩特市'),(439,'152200','152202','阿尔山市'),(440,'152200','152221','科尔沁右翼前旗'),(441,'152200','152222','科尔沁右翼中旗'),(442,'152200','152223','扎赉特旗'),(443,'152200','152224','突泉县'),(444,'152500','152501','二连浩特市'),(445,'152500','152502','锡林浩特市'),(446,'152500','152522','阿巴嘎旗'),(447,'152500','152523','苏尼特左旗'),(448,'152500','152524','苏尼特右旗'),(449,'152500','152525','东乌珠穆沁旗'),(450,'152500','152526','西乌珠穆沁旗'),(451,'152500','152527','太仆寺旗'),(452,'152500','152528','镶黄旗'),(453,'152500','152529','正镶白旗'),(454,'152500','152530','正蓝旗'),(455,'152500','152531','多伦县'),(456,'152900','152921','阿拉善左旗'),(457,'152900','152922','阿拉善右旗'),(458,'152900','152923','额济纳旗'),(459,'210100','210101','市辖区'),(460,'210100','210102','和平区'),(461,'210100','210103','沈河区'),(462,'210100','210104','大东区'),(463,'210100','210105','皇姑区'),(464,'210100','210106','铁西区'),(465,'210100','210111','苏家屯区'),(466,'210100','210112','东陵区'),(467,'210100','210113','新城子区'),(468,'210100','210114','于洪区'),(469,'210100','210122','辽中县'),(470,'210100','210123','康平县'),(471,'210100','210124','法库县'),(472,'210100','210181','新民市'),(473,'210200','210201','市辖区'),(474,'210200','210202','中山区'),(475,'210200','210203','西岗区'),(476,'210200','210204','沙河口区'),(477,'210200','210211','甘井子区'),(478,'210200','210212','旅顺口区'),(479,'210200','210213','金州区'),(480,'210200','210224','长海县'),(481,'210200','210281','瓦房店市'),(482,'210200','210282','普兰店市'),(483,'210200','210283','庄河市'),(484,'210300','210301','市辖区'),(485,'210300','210302','铁东区'),(486,'210300','210303','铁西区'),(487,'210300','210304','立山区'),(488,'210300','210311','千山区'),(489,'210300','210321','台安县'),(490,'210300','210323','岫岩满族自治县'),(491,'210300','210381','海城市'),(492,'210400','210401','市辖区'),(493,'210400','210402','新抚区'),(494,'210400','210403','东洲区'),(495,'210400','210404','望花区'),(496,'210400','210411','顺城区'),(497,'210400','210421','抚顺县'),(498,'210400','210422','新宾满族自治县'),(499,'210400','210423','清原满族自治县'),(500,'210500','210501','市辖区'),(501,'210500','210502','平山区'),(502,'210500','210503','溪湖区'),(503,'210500','210504','明山区'),(504,'210500','210505','南芬区'),(505,'210500','210521','本溪满族自治县'),(506,'210500','210522','桓仁满族自治县'),(507,'210600','210601','市辖区'),(508,'210600','210602','元宝区'),(509,'210600','210603','振兴区'),(510,'210600','210604','振安区'),(511,'210600','210624','宽甸满族自治县'),(512,'210600','210681','东港市'),(513,'210600','210682','凤城市'),(514,'210700','210701','市辖区'),(515,'210700','210702','古塔区'),(516,'210700','210703','凌河区'),(517,'210700','210711','太和区'),(518,'210700','210726','黑山县'),(519,'210700','210727','义 县'),(520,'210700','210781','凌海市'),(521,'210700','210782','北宁市'),(522,'210800','210801','市辖区'),(523,'210800','210802','站前区'),(524,'210800','210803','西市区'),(525,'210800','210804','鲅鱼圈区'),(526,'210800','210811','老边区'),(527,'210800','210881','盖州市'),(528,'210800','210882','大石桥市'),(529,'210900','210901','市辖区'),(530,'210900','210902','海州区'),(531,'210900','210903','新邱区'),(532,'210900','210904','太平区'),(533,'210900','210905','清河门区'),(534,'210900','210911','细河区'),(535,'210900','210921','阜新蒙古族自治县'),(536,'210900','210922','彰武县'),(537,'211000','211001','市辖区'),(538,'211000','211002','白塔区'),(539,'211000','211003','文圣区'),(540,'211000','211004','宏伟区'),(541,'211000','211005','弓长岭区'),(542,'211000','211011','太子河区'),(543,'211000','211021','辽阳县'),(544,'211000','211081','灯塔市'),(545,'211100','211101','市辖区'),(546,'211100','211102','双台子区'),(547,'211100','211103','兴隆台区'),(548,'211100','211121','大洼县'),(549,'211100','211122','盘山县'),(550,'211200','211201','市辖区'),(551,'211200','211202','银州区'),(552,'211200','211204','清河区'),(553,'211200','211221','铁岭县'),(554,'211200','211223','西丰县'),(555,'211200','211224','昌图县'),(556,'211200','211281','调兵山市'),(557,'211200','211282','开原市'),(558,'211300','211301','市辖区'),(559,'211300','211302','双塔区'),(560,'211300','211303','龙城区'),(561,'211300','211321','朝阳县'),(562,'211300','211322','建平县'),(563,'211300','211324','喀喇沁左翼蒙古族自治县'),(564,'211300','211381','北票市'),(565,'211300','211382','凌源市'),(566,'211400','211401','市辖区'),(567,'211400','211402','连山区'),(568,'211400','211403','龙港区'),(569,'211400','211404','南票区'),(570,'211400','211421','绥中县'),(571,'211400','211422','建昌县'),(572,'211400','211481','兴城市'),(573,'220100','220101','市辖区'),(574,'220100','220102','南关区'),(575,'220100','220103','宽城区'),(576,'220100','220104','朝阳区'),(577,'220100','220105','二道区'),(578,'220100','220106','绿园区'),(579,'220100','220112','双阳区'),(580,'220100','220122','农安县'),(581,'220100','220181','九台市'),(582,'220100','220182','榆树市'),(583,'220100','220183','德惠市'),(584,'220200','220201','市辖区'),(585,'220200','220202','昌邑区'),(586,'220200','220203','龙潭区'),(587,'220200','220204','船营区'),(588,'220200','220211','丰满区'),(589,'220200','220221','永吉县'),(590,'220200','220281','蛟河市'),(591,'220200','220282','桦甸市'),(592,'220200','220283','舒兰市'),(593,'220200','220284','磐石市'),(594,'220300','220301','市辖区'),(595,'220300','220302','铁西区'),(596,'220300','220303','铁东区'),(597,'220300','220322','梨树县'),(598,'220300','220323','伊通满族自治县'),(599,'220300','220381','公主岭市'),(600,'220300','220382','双辽市'),(601,'220400','220401','市辖区'),(602,'220400','220402','龙山区'),(603,'220400','220403','西安区'),(604,'220400','220421','东丰县'),(605,'220400','220422','东辽县'),(606,'220500','220501','市辖区'),(607,'220500','220502','东昌区'),(608,'220500','220503','二道江区'),(609,'220500','220521','通化县'),(610,'220500','220523','辉南县'),(611,'220500','220524','柳河县'),(612,'220500','220581','梅河口市'),(613,'220500','220582','集安市'),(614,'220600','220601','市辖区'),(615,'220600','220602','八道江区'),(616,'220600','220621','抚松县'),(617,'220600','220622','靖宇县'),(618,'220600','220623','长白朝鲜族自治县'),(619,'220600','220625','江源县'),(620,'220600','220681','临江市'),(621,'220700','220701','市辖区'),(622,'220700','220702','宁江区'),(623,'220700','220721','前郭尔罗斯蒙古族自治县'),(624,'220700','220722','长岭县'),(625,'220700','220723','乾安县'),(626,'220700','220724','扶余县'),(627,'220800','220801','市辖区'),(628,'220800','220802','洮北区'),(629,'220800','220821','镇赉县'),(630,'220800','220822','通榆县'),(631,'220800','220881','洮南市'),(632,'220800','220882','大安市'),(633,'222400','222401','延吉市'),(634,'222400','222402','图们市'),(635,'222400','222403','敦化市'),(636,'222400','222404','珲春市'),(637,'222400','222405','龙井市'),(638,'222400','222406','和龙市'),(639,'222400','222424','汪清县'),(640,'222400','222426','安图县'),(641,'230100','230101','市辖区'),(642,'230100','230102','道里区'),(643,'230100','230103','南岗区'),(644,'230100','230104','道外区'),(645,'230100','230106','香坊区'),(646,'230100','230107','动力区'),(647,'230100','230108','平房区'),(648,'230100','230109','松北区'),(649,'230100','230111','呼兰区'),(650,'230100','230123','依兰县'),(651,'230100','230124','方正县'),(652,'230100','230125','宾 县'),(653,'230100','230126','巴彦县'),(654,'230100','230127','木兰县'),(655,'230100','230128','通河县'),(656,'230100','230129','延寿县'),(657,'230100','230181','阿城市'),(658,'230100','230182','双城市'),(659,'230100','230183','尚志市'),(660,'230100','230184','五常市'),(661,'230200','230201','市辖区'),(662,'230200','230202','龙沙区'),(663,'230200','230203','建华区'),(664,'230200','230204','铁锋区'),(665,'230200','230205','昂昂溪区'),(666,'230200','230206','富拉尔基区'),(667,'230200','230207','碾子山区'),(668,'230200','230208','梅里斯达斡尔族区'),(669,'230200','230221','龙江县'),(670,'230200','230223','依安县'),(671,'230200','230224','泰来县'),(672,'230200','230225','甘南县'),(673,'230200','230227','富裕县'),(674,'230200','230229','克山县'),(675,'230200','230230','克东县'),(676,'230200','230231','拜泉县'),(677,'230200','230281','讷河市'),(678,'230300','230301','市辖区'),(679,'230300','230302','鸡冠区'),(680,'230300','230303','恒山区'),(681,'230300','230304','滴道区'),(682,'230300','230305','梨树区'),(683,'230300','230306','城子河区'),(684,'230300','230307',&
  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,以下是基于uniapp的城市选择器封装代码: 1. 在components文件夹下新建一个CityPicker文件夹,里面新建CityPicker.vue文件: ``` <template> <div class="city-picker"> <van-picker :columns="columns" @change="onChange" @confirm="onConfirm" @cancel="onCancel" > <template #title> <div class="city-picker-header"> <van-icon name="arrow-left" size="20" @click="onCancel" /> <span class="city-picker-title">{{title}}</span> </div> </template> </van-picker> </div> </template> <script> import { mapState } from 'vuex'; export default { props: { title: { type: String, default: '选择城市' }, visible: { type: Boolean, default: false }, value: { type: Array, default() { return [null, null, null]; } } }, computed: mapState({ cityData: state => state.city.cityData }), data() { return { columns: [ { values: [] }, { values: [] }, { values: [] } ], currentProvince: '', currentCity: '', currentDistrict: '' }; }, methods: { initColumns() { const { columns } = this; const provinceList = Object.keys(this.cityData); const province = this.currentProvince || provinceList[0]; const city = this.currentCity || Object.keys(this.cityData[province])[0]; const district = this.currentDistrict || this.cityData[province][city][0]; columns[0].values = provinceList; columns[1].values = Object.keys(this.cityData[province]); columns[2].values = this.cityData[province][city]; columns.forEach(column => { column.defaultIndex = 0; }); this.currentProvince = province; this.currentCity = city; this.currentDistrict = district; }, onChange(picker, value) { const { cityData, columns } = this; const province = columns[0].values[value[0]]; const city = columns[1].values[value[1]]; const district = columns[2].values[value[2]]; if (cityData[province][city].indexOf(district) === -1) { columns[2].values = cityData[province][city]; } }, onConfirm() { this.$emit('input', [ this.currentProvince, this.currentCity, this.currentDistrict ]); this.$emit('confirm', [ this.currentProvince, this.currentCity, this.currentDistrict ]); }, onCancel() { this.$emit('cancel'); } }, watch: { visible(val) { if (val) { this.initColumns(); } }, columns: { deep: true, handler(val) { const { cityData } = this; const province = val[0].values[val[0].defaultIndex]; const city = val[1].values[val[1].defaultIndex]; const district = val[2].values[val[2].defaultIndex]; if (cityData[province][city].indexOf(district) === -1) { val[2].values = cityData[province][city]; this.currentDistrict = cityData[province][city][0]; } this.currentProvince = province; this.currentCity = city; this.currentDistrict = district; } } } }; </script> <style scoped> .city-picker { height: 300px; overflow: hidden; } .city-picker-header { display: flex; justify-content: space-between; align-items: center; padding: 10px; } .city-picker-title { font-weight: bold; font-size: 16px; } </style> ``` 2. 在store文件夹下新建一个city.js文件,里面写入城市数据: ``` export default { state: { cityData: { 北京市: { 北京市: [ '东城区', '西城区', '崇文区', '宣武区', '朝阳区', '丰台区', '石景山区', '海淀区', '门头沟区', '房山区', '通州区', '顺义区', '昌平区', '大兴区', '怀柔区', '平谷区', '密云县', '延庆县' ] }, 天津市: { 天津市: [ '和平区', '河东区', '河西区', '南开区', '河北区', '红桥区', '塘沽区', '汉沽区', '大港区', '东丽区', '西青区', '津南区', '北辰区', '武清区', '宝坻区', '宁河县', '静海县', '蓟县' ] }, 河北省: { 石家庄市: [ '长安区', '桥东区', '桥西区', '新华区', '井陉矿区', '裕华区', '井陉县', '正定县', '栾城县', '行唐县', '灵寿县', '高邑县', '深泽县', '赞皇县', '无极县', '平山县', '元氏县', '赵县', '辛集市', '藁城市', '晋州市', '新乐市', '鹿泉市' ], 唐山市: [ '路南区', '路北区', '古冶区', '开平区', '丰南区', '丰润区', '滦县', '滦南县', '乐亭县', '迁西县', '玉田县', '唐海县', '遵化市', '迁安市' ], 秦皇岛市: [ '海港区', '山海关区', '北戴河区', '青龙满族自治县', '昌黎县', '抚宁县', '卢龙县' ] }, 山西省: { 太原市: [ '小店区', '迎泽区', '杏花岭区', '尖草坪区', '万柏林区', '晋源区', '清徐县', '阳曲县', '娄烦县', '古交市' ], 大同市: [ '城区', '矿区', '南郊区', '新荣区', '阳高县', '天镇县', '广灵县', '灵丘县', '浑源县', '左云县', '大同县' ], 阳泉市: ['城区', '矿区', '郊区', '平定县', '盂县'] } } } }; ``` 3. 在pages文件夹下新建一个Index.vue文件,在里面调用CityPicker组件: ``` <template> <div class="container"> <van-field v-model="value" label="城市" placeholder="请选择城市" readonly @click="showPicker" /> <city-picker :visible.sync="show" :value.sync="value" @confirm="onConfirm" @cancel="onCancel" /> </div> </template> <script> import CityPicker from '@/components/CityPicker/CityPicker'; export default { components: { CityPicker }, data() { return { show: false, value: [null, null, null] }; }, methods: { showPicker() { this.show = true; }, onConfirm(value) { this.value = value; this.show = false; }, onCancel() { this.show = false; } } }; </script> <style scoped> .container { padding: 20px; } </style> ``` 这样一个封装好的城市选择器组件就完成了。可以根据自己的需要进行样式和功能的调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值