查看: 5155|回复: 0

Catia二次开发源码分享: 通过鼠标点击创建直线

[复制链接]

6

主题

4

回帖

60

积分

管理员

积分
60
发表于 2017-4-17 21:56:09 | 显示全部楼层 |阅读模式

请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!

您需要 登录 才可以下载或查看,没有账号?注册

×

4 Q7 c; H0 o9 ~) T) ^% b+ gCatia二次开发源码分享: 通过鼠标点击创建直线2 X  \/ h4 H, Z" p& w' }. f

! R' ]* A5 z" P/ C4 o/ F$ Z" E+ Q2 |$ j" K- p

1 H/ m' G( z& `. q4 F0 I+ ~: b#include "CAARCCreateLine.h"
, ]  T& a: ]; G1 J- s) m3 j#include "CATIndicationAgent.h"
/ q0 Z1 N9 M6 s* M) o: ?#include "CATMathPlane.h"! }( p2 y2 Z" H! [1 |, i  W0 ?1 V! i

6 x/ J% Z! M4 ~3 Z& b, O, ?#include "CATCreateExternalObject.h"
* M8 x1 F. U( p, \6 L9 j3 O
9 Z8 c5 \% v: d9 K, ~#include "CATMathPoint2D.h"
. F; w/ K( w- G3 h: h. x, F( k" y#include "CATMathPoint.h"7 r. O5 b" d& ~* l
#include "CATMathPlane.h"
/ t% [! @; l6 M7 q, o
& \7 _6 J$ c, U. i/ U) P#include "CATIGSMPoint.h"7 a3 A0 y' e5 E8 C6 {" X4 \/ r
#include "CATIGSMLinePtPt.h"
5 J) l+ r! Z" Q* j  L9 b& T& x
/ \3 L1 @( R; o% w#include "CATFrmEditor.h"
5 h0 ?1 r- u2 Y4 z) ]% z#include "CATPathElement.h"
/ J  a$ h3 a& W; T
3 W( X% W" `; S' O2 P' p#include "CATIProduct.h"+ Q1 |' c' D( O4 P, V8 e
#include "CATILinkableObject.h"2 g: S6 n' Y6 h( D* i2 j
#include "CATDocument.h"% J4 U9 X3 K, W. A
1 C6 P* g" n/ L2 u# O
#include "CATIContainerOfDocument.h"
$ O0 v) ?! @$ |1 B5 T0 c! y( u
* M) d: s4 v( N: w#include "CATIGSMProceduralView.h"
2 C4 h/ m  W, y3 D  l- g+ d9 m& B4 w& w' S) ^
#include "CATIContainer.h"
/ x- Q& i1 y: Y1 H# I6 B1 {#include "CATIGSMFactory.h"
* J0 D% y) z; J2 L' Q/ @0 H. Q# {% x0 U
#include "CATISpecObject.h"8 f2 J) j( ^7 v6 V3 @" |. o
CATCreateClass( CAARCCreateLine);/ m- Q( |3 g( c( r+ X

9 \- b+ }- a9 B4 F: j2 R6 G! Y/ ]
//-------------------------------------------------------------------------
, V% m; s& H5 u9 h3 ]& O// Constructor+ G0 {7 k7 S% U
//-------------------------------------------------------------------------
6 y% A- W( b+ a* X& F/ _CAARCCreateLine::CAARCCreateLine() :
1 K# M; c& G/ {" q1 w  CATStateCommand ("CAARCCreateLine", CATDlgEngOneShot, CATCommandModeExclusive)
; t; J6 x/ ~3 I//  Valid states are CATDlgEngOneShot and CATDlgEngRepeat
! ~& k  l2 n( O: }  ,_IndicationOnePoint(NULL),_IndicationTwoPoint(NULL)- Q: k8 {" J, l1 D% O* b% F! k
{
' R3 e, C( a9 }+ [: J7 p* O5 n}
( y' Y$ B$ c8 {2 O: o6 }
2 Q* B2 T. A& i* k  ?5 x1 V//-------------------------------------------------------------------------
/ ^. M9 W8 \- J# i// Destructor
6 i( w# R1 H. [: B( H! e//-------------------------------------------------------------------------5 w: }1 w6 k" S2 F; p
CAARCCreateLine::~CAARCCreateLine()
7 E0 ?0 T$ f3 i( R{
9 k) ]& p- s# |# @9 ?) f   if (_IndicationOnePoint != NULL) . |" E+ F+ t; {4 M5 ?3 T9 o: h
      _IndicationOnePoint->RequestDelayedDestruction();7 E8 A6 I# n' i; R) q
   if (_IndicationTwoPoint != NULL)
6 m. p, \7 F& n7 Q3 K     _IndicationTwoPoint->RequestDelayedDestruction();
! `0 @, b* V/ G' W2 _7 f7 K}
6 J& `" }+ U4 [" v' q' V/ d* C/ ?6 ~1 y' ]7 @
; r# `* R' M7 N6 P! q
//-------------------------------------------------------------------------
) _! L. q# K3 P# u8 q( [// BuildGraph(): Q7 k$ H! k8 y" ?
//-------------------------------------------------------------------------7 E+ c9 ]$ Q- l7 X2 D& O# v- O
void CAARCCreateLine::BuildGraph()
. n1 J0 ?. T; `/ }# Z, a{
! W( k  |# C7 Q
! u7 G+ @7 J1 k# L
. w8 j2 W! z5 \7 G  // TODO: Define the StateChart ' a+ b8 \0 O; J+ V
  // ---------------------------7 n' ~: z" R. a7 ?3 `
  _IndicationOnePoint = new CATIndicationAgent ("IndicationOnePoint");
& D3 N. e8 l" G  AddCSOClient(_IndicationOnePoint);
/ K9 [  c7 W9 e2 Q* k$ ?( l' m# K/ X' R, a+ z* N
  _IndicationTwoPoint = new CATIndicationAgent ("IndicationTwoPoint");
& b6 G0 o( e! l$ Q* v) v+ M, ]1 z
+ m! r" ^3 k! L5 H. V7 r2 B2 Z  CATMathPlane PlaneXY;
+ ]! ]: R- Z8 p/ R' }: B- Y  _IndicationOnePoint -> SetMathPlane (PlaneXY);- Y0 t3 n( L5 M9 |' M
  _IndicationTwoPoint -> SetMathPlane (PlaneXY);. t  C6 |/ B& O' L* |
: r0 X5 N1 H) T3 {( Q
  CATDialogState * initialStateOne = GetInitialState("选择第一个点位置");
7 f9 v9 C2 A+ u6 ~4 h; e2 C  initialStateOne -> AddDialogAgent (_IndicationOnePoint);
) Z9 a. S0 r/ g4 K$ y% C* i0 K; T! _/ {: O4 B7 }
  CATDialogState * initialStateTwo = AddDialogState("选择第二个点位置");
; q  P2 t' e: ?& j" F$ F  initialStateTwo -> AddDialogAgent (_IndicationTwoPoint);' N. w& x3 ~% V3 N3 x8 E
+ ~6 s! z. d9 Q: d
  AddTransition( initialStateOne,
0 b, m! C) T! C: u                 initialStateTwo,
* N3 W  k& t( g: N' Q% k6 _% L                 IsOutputSetCondition (_IndicationOnePoint),+ V7 q  @: K; k; o* A+ J
                 Action ((ActionMethod) &CAARCCreateLine::ActionOne));+ Y9 M! h& M/ Z( z# A
% B2 t1 l9 W! q0 U; q' P. P' V* e
  AddTransition( initialStateTwo, 2 ?+ i- f: T5 F% Y1 @1 k- w
                NULL,   U" R9 c, m7 k" p3 Y
                IsOutputSetCondition (_IndicationTwoPoint),; \0 L) H& @# s0 g9 I$ Y5 E  u
                Action ((ActionMethod) &CAARCCreateLine::ActionTwo));9 A; G3 h; ?0 T( h+ T$ J8 V! l( P
}
2 B) u% r; M2 H* [' N' l/ m, M5 {  l- |, x
2 E9 U$ }2 H' s. E  H7 w/ o! y5 J
//-------------------------------------------------------------------------# ~  y% m2 b3 m4 _9 K9 W9 F2 `
// ActionOne ()
) m! o# _/ F3 f$ {* d8 z//-------------------------------------------------------------------------
6 f$ ]# S+ L8 \  e) [/ LCATBoolean CAARCCreateLine::ActionOne( void *data )6 V1 _# t" [3 p& D' ^1 o$ F
{
9 p' m+ }2 n9 p  }2 A  // TODO: Define the action associated with the transition ) ]9 {: x& b% w; W: b2 ^  [! p
  // ------------------------------------------------------: S! x8 n7 O2 ~1 Y5 _! O' X
  CATMathPoint2D point2D = _IndicationOnePoint->GetValue();//获得一个2D的点
8 g4 e# A0 u& d# ?. |9 F( n( r' |' [9 u6 }% Z
  CATMathPoint Point3D;6 x" N! H* N$ z2 S. J( `) g
  CATMathPlane Plane = _IndicationOnePoint->GetMathPlane();$ |- h2 m$ L; Q+ g- |+ h/ N4 U

" V) Y3 @' u6 y3 `" ^& |  Plane.EvalPoint(point2D.GetX(),point2D.GetY(),Point3D);                //将2D点转换为3D点
# \3 A1 e6 E( M4 G
* U0 i& x4 [% z' b  //设置Container(非根节点)
5 l/ k1 z9 k$ e7 v8 f& q  //获得Editor) \2 g7 V5 S& t
  CATFrmEditor* pEditor = CATFrmEditor::GetCurrentEditor();
1 a/ F6 N( `! A# e5 i% b0 V$ x! @( s" F* C; L
  //得到当前对象的文档& ~, X; N3 ]4 O: u
  CATDocument * pDocument = NULL ;
  I( g0 k5 P* d# b3 l9 |* H. L  S9 \
  //取得当前活动对象6 c% l: o* v* Q8 G
  CATPathElement activePath = pEditor->GetUIActiveObject();
5 Z; f9 N. @$ Z4 F  n1 n/ D9 ^1 I- c- [3 Y, K( v
  //取得当前活动的product
" J8 Y6 b& _* s- D  CATIProduct *pActiveProduct = (CATIProduct *)activePath.SearchObject(CATIProduct::ClassName());4 o3 O9 n2 F2 c7 p* }, a
& D" u+ s/ _' O, b1 i! _- k3 M
  //当前活动对象不存在
, T7 W' @  x+ E7 N2 L1 J  i  if (pActiveProduct == NULL)/ b. S! K1 I: \/ `) N1 `# f
  {
$ X6 x5 w8 j" J" N. N0 r3 |. E/ f    pDocument = pEditor->GetDocument();! }$ h4 [' B$ T( N( O, q% I
  }8 o; M4 x7 f: w, e
  else
: H* c  J+ G' t! X  {/ b0 }; f5 W  K# R3 g  ~1 p
    CATIProduct_var spRef = pActiveProduct->GetReferenceProduct();
& r. A2 T7 F. \8 S    //当前对象的引用对象是否存在, o4 Z% x9 W/ R- X) f
    if ( NULL_var == spRef )( X  s9 J6 o1 [/ c  |/ n) |4 P
    {& i1 G2 Z2 W. L# U) Y* l# b, T
      return FALSE;1 g7 x% _# x+ I: ]
    }
1 }6 K; f7 R# |" i+ Q  s
7 g8 m4 S2 p" x. }& ]3 o8 R0 X& ~    //当前对象的链接对象# S: z" l1 R+ S) M" N) ]" ^
    CATILinkableObject * piLinkableObject = NULL;( {. S- z2 J6 j' _( J2 j7 x
    HRESULT rc = spRef->QueryInterface( IID_CATILinkableObject, (void**)& piLinkableObject );                           
$ Z2 q( M$ l) M/ X    if ( FAILED(rc) )
! p& h6 B% ?5 G: W. h+ A: A! X    {
9 n; l/ v* |5 r7 |      piLinkableObject->Release();
3 @5 U; F! a! r$ y8 x: L" |9 x      piLinkableObject = NULL ;( N" C6 q. u) W: X" b* w
      return FALSE;
9 l6 i  b: \7 C) v! T    }$ E* O& e4 H" G

/ m/ k6 o7 Y+ w2 A2 Y$ X    //得到当前对象的文档8 ?% S% ], S. ~7 i1 |: W
    pDocument = piLinkableObject->GetDocument();) X% A( H* o) y1 D
    piLinkableObject->Release();
' W: _+ n$ p7 R4 y2 ^) O    piLinkableObject = NULL ;3 ?' H$ Q4 S) f* N. C+ H

5 e/ ?1 |! P( L6 o0 x    if ( NULL == pDocument)% v& z5 i$ V$ J) U/ M  \% {
    {* z4 o( S5 c" G: r7 i1 [( d
      return FALSE;
% p1 I5 r+ U0 L( @1 \    }+ ]# [. Y  y2 Q) ~) W7 \- O
  }
; y) k( d4 I( _6 V2 F8 Q7 W) u! i) c9 N! _
  //得到文档容器集
0 o! _8 Z/ v2 U) V" t4 S3 r  CATIContainerOfDocument * pIContainerOfDocument = NULL;7 M* H6 ~/ Y; y
  HRESULT rc = pDocument->QueryInterface(IID_CATIContainerOfDocument, (void**)&pIContainerOfDocument);9 W  @# m5 T4 e( l& k2 m) W
  if (FAILED(rc))+ h, s2 u4 Y  m8 x" Z/ u! E
  {" n% h  c* g% ]
    //pIContainerOfDocument->Release();1 \, ~( m9 p  ]6 R$ S) I. @
    pIContainerOfDocument = NULL ;, Y1 @. K$ s2 U
    return FALSE;* k% J' @8 M; m5 Z, T
  }8 _  P9 f% t; p
3 E5 ]1 U7 H# ?1 L+ s& G- O
  //获得Document+ i7 q3 \6 K2 _1 w9 ?3 r
  CATIContainer* _pContainer = NULL;        2 G% d& _; n9 k) k" O- v
  //获得SpecContainer- [3 a) r) L$ r2 ]
  HRESULT hr = pIContainerOfDocument->GetSpecContainer(_pContainer);. E9 }$ i+ H% {) Q7 P3 j
        - \, _8 A& \) d) q* w
  //GSM工厂
' G; V+ ~8 m- s& W; ]& p  CATIGSMFactory_var spGSMFactory = NULL_var;
0 t. {: G$ N' X  //设置工厂                , u; ?( T/ Q# B7 M/ n  ^# ?) `
  spGSMFactory = _pContainer;                                                                       
0 U+ G. F; s9 ]( [$ G9 ?- h) j) ^
7 P- T4 ?2 n7 |/ F2 W) `  CATIGSMPoint_var spPoint = spGSMFactory->CreatePoint(Point3D);  _: Q' ]* v1 `, r% h

+ E2 {+ U, ?/ r2 S0 B* @) v, O  spSpecPoint1= spPoint;                                       
1 s9 V$ b: J$ i6 |1 b
/ L( ^  {" c9 p$ v2 P6 M8 C/ v  CATIGSMProceduralView_var spSndPntObj = spSpecPoint1;  f* X) P# H3 O" Y/ n% F2 x

/ ?2 c4 A8 p2 \# L0 d, y  //*将点显示在屏幕上/ a8 I' u& q7 m5 l# b! N5 b
  spSndPntObj->InsertInProceduralView();
+ k7 x0 w) ?, d( x6 y4 v$ L
! {: ]6 f- S! I  spSpecPoint1->Update();+ f2 m1 y- k4 J9 Y. Y" J+ W
9 Q$ n! n9 X) Q) f! D) l5 h& u
  return TRUE;
' h0 {1 v) w- X& s0 O# Z5 w; O}
- w2 m7 R" l- e
+ o! Z0 D, @" Y( f, }1 E5 `//-------------------------------------------------------------------------( i: o9 ^+ v- x' c% x' m; C
// ActionTwo ()
1 V6 U# \7 ^  A//-------------------------------------------------------------------------
  x0 i0 [3 `8 u" ~% C# qCATBoolean CAARCCreateLine::ActionTwo( void *data )$ v% |) p+ C& C, m0 W( T: a
{7 S/ E. o6 \# F8 G2 o/ ^+ W' k) L
  // TODO: Define the action associated with the transition # p! q' Q" A( _$ k! p
  // ------------------------------------------------------
  G: t# J! k# i. I- _& o  CATMathPoint2D point2D = _IndicationTwoPoint->GetValue();//获得一个2D的点
- _- W; ^% v1 c9 @- x  y, |$ N& w2 v1 N5 R
  CATMathPoint Point3D;" |' }0 {4 }- h' H
  CATMathPlane Plane = _IndicationTwoPoint->GetMathPlane();2 G5 U7 r+ l! S1 A: J/ H
9 D7 L) }6 q, E6 ?9 y* ]* i
  Plane.EvalPoint(point2D.GetX(),point2D.GetY(),Point3D);                //将2D点转换为3D点8 v" g$ {+ d7 W7 ~' N7 `

9 t( S/ W2 g4 k0 B  //设置Container(非根节点)' P  J: z0 a8 n# z5 H# `( m
  //获得Editor4 j3 k7 ^$ W" A* D  P* _. Z6 H
  CATFrmEditor* pEditor = CATFrmEditor::GetCurrentEditor();
7 Y" h6 L- k4 q
6 L, X, Z' w, [1 x' ?  //得到当前对象的文档" o1 f! u. ?5 y0 h1 Q6 f* g
  CATDocument * pDocument = NULL ;2 k+ E5 v* }* D/ ~

+ x- K3 z# e' J) S# A" k  //取得当前活动对象# I  p1 T$ K/ u& n% D: n
  CATPathElement activePath = pEditor->GetUIActiveObject();$ j7 r9 V0 B, e, x5 A
% h! t9 b/ ]  W, B3 t+ A
  //取得当前活动的product
( H7 U0 j6 f8 f; |  CATIProduct *pActiveProduct = (CATIProduct *)activePath.SearchObject(CATIProduct::ClassName());
' L- Q) \, l, N0 I- {2 \8 ?. Y# z) H$ w" P5 e9 M) I
  //当前活动对象不存在& }, h4 _: J2 V- I; L) Q3 O3 ~
  if (pActiveProduct == NULL)  c" M; o' V) V6 x
  {, v% a3 T, x( [4 k& y. [
    pDocument = pEditor->GetDocument();
2 ?6 F9 l- k' i  ~1 n4 v  }1 r3 B1 `; p, G3 K, K5 H' |
  else
& F# Q+ w2 f1 ]  {  K& {6 l. K% A+ v, w
    CATIProduct_var spRef = pActiveProduct->GetReferenceProduct();& N# ?& r3 n: q2 }
    //当前对象的引用对象是否存在
$ R! @( u. {; r7 o6 }/ e( o    if ( NULL_var == spRef )- s& Z! E( _6 j9 ~
    {1 [) E1 [" E, M6 F& z- X9 C0 V+ n
      return FALSE;. t2 o* n1 `9 K/ u* w" {  M9 X
    }* _; c! Q& H6 o1 @2 ~
9 a, I5 f' L. D# [5 b! @; C: t4 b6 F
    //当前对象的链接对象0 N) Y3 w$ E3 C/ F! w' K; A% R
    CATILinkableObject * piLinkableObject = NULL;
8 s% ?$ g- {$ p    HRESULT rc = spRef->QueryInterface( IID_CATILinkableObject, (void**)& piLinkableObject );                            9 Y, i  ?' {9 w$ x
    if ( FAILED(rc) )* v$ {5 S6 B; `8 Y
    {! w  C) {9 t& \+ X
      piLinkableObject->Release();+ t2 U5 o# a+ E" V
      piLinkableObject = NULL ;; M) ]" Y: s) b) M
      return FALSE;5 ?8 T# L% P9 t% y) S" x
    }' d; r7 G( h# B( D  \: o9 m' i- I

) V4 x! k5 u. ^    //得到当前对象的文档
/ M( M! N1 w+ [    pDocument = piLinkableObject->GetDocument();
- i1 u7 C/ q) q5 D! q+ C) n    piLinkableObject->Release();
2 @5 E8 j6 I; ?) C" t    piLinkableObject = NULL ;
# P7 |+ m  }2 V2 I& r: L# z- e6 g
    if ( NULL == pDocument)' K& I+ Y% b% u' n
    {
: z+ ~! P7 K2 i; F, {. W. f      return FALSE;
3 \! k- B* \7 O+ l    }: f' h% r6 s& z6 D0 E" B
  }6 ~- G4 ]+ A' P8 A. T) w

, _/ w; O+ ~! k# R" }0 C  ]* W  //得到文档容器集
# u- c! N! a( c" z8 N2 W( i  CATIContainerOfDocument * pIContainerOfDocument = NULL;+ w. f1 y' E% ]6 H3 ?% ^, s
  HRESULT rc = pDocument->QueryInterface(IID_CATIContainerOfDocument, (void**)&pIContainerOfDocument);; b1 h( L6 L7 V; g! D) u  I$ F
  if (FAILED(rc))
1 _+ V* _6 r7 m: f: X  {/ K, A. P7 l( @0 T
    //pIContainerOfDocument->Release();
/ _6 l( s) J, p/ X1 j0 e+ G5 j    pIContainerOfDocument = NULL ;
1 R. e) Y0 ~7 E; j7 f) ]0 e/ r    return FALSE;
7 }" K, {) r9 W- I7 j: V% E3 s  }$ \2 ~# u3 M3 a
; }: a. U5 {5 k% X+ e# l
  //获得Document  k* ~, m4 U0 s- g% s& v+ K  O
  CATIContainer* _pContainer = NULL;        - W( n' N- `. {
  //获得SpecContainer. A6 |3 L1 u& x( b* R
  HRESULT hr = pIContainerOfDocument->GetSpecContainer(_pContainer);
9 l) T6 @: Z+ b$ e4 {       
+ z: l" |& u, V6 l  //GSM工厂
9 [7 `( ?1 r: w$ ?9 X/ K0 K: I  CATIGSMFactory_var spGSMFactory = NULL_var;2 _+ b1 v: F+ [' I6 r
  //设置工厂                1 K, s! Z* [7 C( ~, a
  spGSMFactory = _pContainer;                                                                       
: ^9 f6 r9 y0 S3 |7 E  N" [' e/ w. G
  CATIGSMPoint_var spPoint = spGSMFactory->CreatePoint(Point3D);5 ~# q6 @# R7 Y8 x& i/ w% {
+ ~+ F0 s. H5 ~1 G, A! @2 [( j( G% S
  CATISpecObject_var spSpecPoint2= spPoint;                                       
/ Q: L+ R% j8 d) C* P  O0 N1 p& `9 H$ T$ @6 P
  CATIGSMProceduralView_var spSndPntObj = spSpecPoint2;
% p# j: W" [: v8 z
8 T/ Q- L! i" `  //*将点显示在屏幕上
$ o2 {9 e& x" @/ o* ^) v: ?  spSndPntObj->InsertInProceduralView();
* m3 p. B1 y# i1 P
9 X: d, c& I8 X1 {3 s! z( u: r  spSpecPoint2->Update();2 O% |* ]: l. m

1 F7 \" u. C# j( l8 n) x3 B0 a  //生成线
( Q9 p  K- Y1 ~3 \9 a3 G/ ~  CATIGSMLinePtPt_var spLine = spGSMFactory->CreateLine(spSpecPoint1, spSpecPoint2, NULL_var);
# I- }' u8 u. }* S, R# ?1 U* C4 Y1 T; Y/ a
  CATISpecObject_var spSpecLine= spLine;                                        5 v" W/ d  U8 t  L9 n6 K

- i  ^0 t/ r% ?6 J  O# s; G: B+ Z  CATIGSMProceduralView_var spSndPntObjLine = spSpecLine;
: K" o" a; P* B( B# R
4 D( J8 ^7 m5 N, r2 M  z  //*将线显示在屏幕上7 K5 T1 \' B  r' {9 C' t# R& H; p! X& K
  spSndPntObjLine->InsertInProceduralView();
5 ?5 _$ b2 W: P( b5 o( t/ s" R2 d% D7 A) {/ |, b# h
  spSpecLine->Update();
  \  h* ~, ?0 G8 t" }6 O: e0 x! w" ~
  return TRUE;; n% }4 C5 x) W* @
}+ U8 r3 P- n3 `( C

. J! S5 ]; D" O+ G  C
, ]9 e, {# u$ h% U" Y  I+ G7 Z' ~
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 www.doteam.tech
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

在本版发帖
关注公众号
QQ客服返回顶部