首頁>其它>

平臺管理後臺與商家選單資源管理

平臺管理後臺是為電商平臺的運營方提供服務的,它主要包含商家管理和一些公共配置管理的功能。在商家管理的設計中,包括商家的註冊、稽核、商家使用者的許可權管理和選單資源管理等功能。除一些公共管理功能的設計外,平臺管理後臺本身也有安全控制管理的設計。

平臺管理後臺的專案工程為manage-microservice,完整的原始碼可以從本書原始碼中下載。

本章例項程式碼的分支為V2.1,檢出請注意更新。平臺管理後臺的開發主要包含兩大部分內容,一部分是管理後臺本身的訪問控制管理設計,另一部分是商家及其選單資源管理。這兩部分的功能都在模組manage-web 中實現。

平臺管理後臺資料服務設計

平臺管理後臺是一個獨立的應用系統,它有自身的使用者體系和獨立的許可權管理設計。平臺管理後臺的訪問控制及其許可權管理主要由操作員、角色和部門等實體組成,這幾個實體的關聯關係是:一個操作員只能從屬於一個部門,同時一個操作員可以擁有多個角色。

實體建模

為實現訪問控制及簡單的許可權管理設計,我們定義了三個實體物件,分別是操作員、角色和部門。

操作員的實體物件Operators主要由名稱、郵箱、性別、密碼和所屬部門等屬性組成,實現程式碼如下所示:

@Entity@Table (name = "toperator")public class Operators extends IdEntity{private String name;private string email;private Integer sex;@DateTimeFormat (pattern = "yyyy-MM-dd HH:mm :ss")ecolumn(name = "created",columnDefinition = "timestamp defaultCurrent timestamp ")@Temporal (TemporalType.TIMESTAMP)private Date created;private String password;@ManyToOne@JoinColumn (name = "did")@JsonBackReferenceprivate Department department;@ManyToMany(cascade ={},fetch = FetchType.EAGER)@JoinTable(name = "operator part",joinColumns = {@JoinColumn(name - "operator_id")},inverseJoinColumns = {@JoinColumn(name = "part_id")})private List<Part> parts = new ArrayList<>();public Operators() {}...}

在這一設計中,主要實現了操作員的關聯關係。一方面以多對一的關係關聯了部門實體,即一個操作員只能屬於一個部門;另一方面以多對多的關係關聯了角色實體,即一個操作員可以擁有多個角色。

角色的實體物件Part主要由名稱和建立時間等屬性組成,實現程式碼如下所示:

@Entity@Table(name = "t part")public class Part extends IdEntity {private String name;@DateTimeFormat (pattern = "yyyy-MM-dd HH:mm:ss")@Column (name = "created",columnDefinition = "timestamp defaultcurrenttimestamp")@Temporal(TemporalType.TIMESTAMP)private Date created;public Part(){}...}

這個角色設計並沒有關聯資源,有關它的訪問許可權設計將在本章後面使用一種更加簡單的方式實現。

部門的實體物件Department主要由名稱和建立時間等屬性組成,實現程式碼如下所示:

@Entity@Table(name = "t department")public class Department extends IdEntity {private String name;@DateTimeFormat (pattern = "yyyy-MM-dd HH:mm :ss")eColumn (name = "created",columnDefinition = "timestamp defaultcurrent timestamp ")@Temporal (TemporalType.TIMESTAMP)private Date created;public Department (){}...}

在實體物件之間的關聯關係設計中,使用了單向關聯的設計原則,即在部門實體設計中,不再與操作員建立關聯關係。如果需要從部門中查詢操作員,則可以透過使用SQL查詢語句實現

在上面的實體物件設計中,都繼承了一個抽象類Baseld,用它實現了物件中ID主鍵的定義,程式碼如下所示:

@MappedSuperclasspublic abstract class Baseld implements Serializable{private static final long serialVersionUID =1L;@Id@Generatedvalue (strategy = GenerationType. IDENTITY)private Long id;public Long getId() {return id;public void setId (Long id){this.id= id;}}

為實體賦予行為

為實體定義一個儲存庫介面,透過繫結JPA儲存庫,就可以為之賦予一些基本行為,實現實體的持久化設計。在儲存庫介面的定義中,還可以透過宣告方法增加一個實體的其他操作方法。

對於上節的操作員實體物件來說,可以透過如下方式設計它的操作方法:

@Repositorypublic interface OperatorRepository extends JpaRepository<Operators,Long>,JpaSpecificationExecutor<0perators> {CQuery ("select t from Operators t where t.name =?1 and t.email =?2")Operators findByNameAndEmail(String name, String email);GQuery ("select distinct u from Operators u where u.name= :name ")Operators findByName (RParam( "name") String name);cQuery ("select distinct u from Operators u where u.id= :id")Operators findById(@Param("id") Long id);@Query("select o from Operators o "+"left join o.parts p"+"where p.id= :id")List<0perators> findByPartId(@Param ("id") Long id);}

這裡聲明瞭幾個方法,都是透過SQL查詢語句擴充套件操作員實體物件操作行為的。其中findByPartld實現了透過部門ID查詢操作員列表的功能。

另外,在角色實體和部門實體的持久化設計中,只要建立一個簡單的儲存庫介面,透過繫結JPA介面,就可以實現基本操作,不再贅述。

資料訪問服務設計

資料訪問服務是對儲存庫介面呼叫的一個服務層封裝設計,透過服務層的開發,可以為儲存庫介面的呼叫提供統一的事務管理,實現其他擴充套件設計。

下面以操作員實體資料訪問服務開發為例進行說明。

對於一般的增刪改查的操作,可以使用如下所示的設計:@Service@Transactionalpublic class OperatorServiceCAutowiredprivate operatorRepository operatorRepository;public String insert (Operators operators) {try{Operators old = findByName (operators .getName());if(old == null) {operatorRepository.save (operators) ;return operators.getId() .toString();}else{return "使用者名稱'"+ old.getName()+”已經存在! ";}catch (Exception e) {e.printStackTrace() ;return e.getMessage() ;}}public string update (Operators operators) {try{operatorRepository. save (operators) ; return operators.getId() . toString() ;}catch (Exception e){e.printStackTrace() ;return e.getMessage() ;}}public String delete (Long id) {try{operatorRepository .deleteById(id) ;return id. toString() ;}catch (Exception e) {e.printStackTrace() ;return e.getMessage() ;}}public List<0perators>findA11(){return operatorRepository.findAl1();}public Operators find0ne (Long id){return operatorRepository.findByOperatorId(id);}public Operators findByName (string name){return operatorRepository.findByName (name) ;public List<Operators> findByPartId (Long partId){return operatorRepository.findByPartId(partId);}}

這些方法都是透過呼叫操作員實體的儲存庫介面實現資料存取操作的。其中,對於操作員來說,因為需要使用使用者名稱進行登入驗證,所以在新增資料時使用了去重檢查。

對於分頁查詢來說,可以透過定義一個Specification實現複雜的查詢,程式碼如下所示:

@service@Transactionalpublic class OperatorService {@Autowiredprivate OperatorRepository operatorRepository;public Page<0perators> findAll (0peratorsVo operatorsVo){Sort sort = Sort.by (Sort.Direction.DESC, "created");Pageable pageable = PageRequest.of(operatorsVo.getPage(),operatorsVo.getsize(), sort);return operatorRepository.findAll (new Specification<Operators>(){@overridepublic Predicate toPredicate (Root<Operators> root, CriteriaQuery<query, CriteriaBuilder criteriaBuilder) {List<Predicate> predicatesList = new ArrayList<Predicate>();if(CommonUtils.isNotNull (operatorsVo.getName())){predicatesList.add (criteriaBuilder.like (root.get ("name"),"g"+operatorsVo.getName() +"o"));}if (CommonUtils.isNotNull(operatorsVo.getCreated())){predicatesList.add (criteriaBuilder.greaterhan (root.get ("created"),operatorsVo. getCreated()));query.where(predicatesList.toArray (newPredicate[predicatesList.size()]));return query.getRestriction();},pageable);}}

其中,分頁查詢的引數可以根據需要進行設計,這裡只提供了操作員名稱和建立日期兩個引數進行查詢。

其中,分頁查詢的引數可以根據需要進行設計,這裡只提供了操作員名稱和建立日期兩個引數進行查詢。

單元測試

在完成資料訪問服務設計之後,可以進行一個單元測試,以驗證設計是否正確。

下面是一個插入資料的測試用例,透過這個測試用例我們可以建立一個登入系統的管理員使用者:

@Runwith (SpringRunner.class)@ContextConfiguration (classes ={JpaConfiguration.class,ManageRestApiApplication.class})@SpringBootTestpublic class BbServiceTest {private static Logger logger =LoggerFactory.getLogger (BbServiceTest.class);@Autowiredprivate OperatorService operatorService;@Autowiredprivate PartService partService;@Autowiredprivate DepartmentService departmentService;@Testpublic void insertData(){Partpart=new Part(;part.setName ( "admins");partService.save(part);Department department = new Department ();department.setName("技術部");departmentService.save(department);Operators operators =new Operators();operators.setName ("admin");operators.setSex(1);operators.set Department (department);List<Part> partList = operators.getParts();partList.add(part);operators.setParts(partList);BCryptPasswordEncoder bc = new BCryptPasswordEncoder();operators.setPassword(bc.encode ( "123456"));operatorService.insert(operators);assert operators.getId() >0: "create error";}}

這個測試用例執行了以下操作:

(1)建立了一個角色,名稱為admins(也可以把它當成一個使用者組)。

(2)建立了一個部門,名稱為技術部。

(3)建立了一個使用者,名稱為admin,並給使用者設定密碼為123456。

如果測試成功透過,則這些生成的資料可以為後面的開發所使用。我們可以使用admin這個使用者作為系統管理員登入系統。

其他測試用例可以參照這個方法來設計。

21
最新評論
  • 康明斯6bt發動機
  • 他的一生,都很金基德