index.vue 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734
  1. <template>
  2. <ToolsDialog
  3. v-if="show"
  4. @onClose="onClose(), $emit('formDrawClose', {source: 'formDraw', value: false})"
  5. title="标绘"
  6. v-model:layout="toolsLayout"
  7. close
  8. expend
  9. >
  10. <div class="base-draw-com" v-loading="loading">
  11. <template v-if="config.isView">
  12. <div class="content">
  13. <div class="content-info">
  14. <Component
  15. :is="transfer.form.com"
  16. :transfer="transfer.form.detail"
  17. v-model:loading="loading"
  18. :isView="config.isView"
  19. :map="map"
  20. ref="ref_formCom"
  21. @pass="(e) => { onClose(); $emit('formDrawClose', {source: 'formDraw', ...e, value: true})}"
  22. @drawDefault="onDrawDefault"
  23. @drawHcq="onDrawHcq"
  24. @drawSmall="onDrawSmall"
  25. @wkt="val => config.wkt = val"
  26. @hcqWkt="val => config.hcqWkt = val"
  27. @smallWkt="val => config.smallWkt = val"
  28. />
  29. </div>
  30. </div>
  31. <div class="bottom-buttons" v-if="config.viewToEdit">
  32. <div class="submit __hover" @click="onEdit">编辑</div>
  33. <div class="cancel __hover" @click="onClose(), $emit('formDrawClose', {source: 'formDraw', value: false})">取消</div>
  34. </div>
  35. </template>
  36. <template v-else>
  37. <div class="base-draw-com-tabs">
  38. <div class="__hover" :class="{active: tab === '1'}" @click="tab = '1'">标绘信息</div>
  39. <div class="__hover" :class="{active: tab === '2'}" @click="tab = '2'">基本信息</div>
  40. </div>
  41. <div class="content">
  42. <div v-show="tab === '1'" class="content-draw">
  43. <div class="__title">形状样式</div>
  44. <CusForm labelWidth="74px" ref="ref_drawForm">
  45. <CusFormColumn
  46. label="形状:"
  47. v-model:param="config.featureType"
  48. >
  49. <template #cus="{handleValidate}">
  50. <div class="feature-type">
  51. <template v-if="config.featureType === 'Point'">
  52. <div><SvgIcon name="point_1" size="28" color="#ffffff"/></div>
  53. </template>
  54. <template v-else-if="config.featureType === 'LineString'">
  55. <div><SvgIcon name="line_1" size="28" color="#ffffff"/></div>
  56. </template>
  57. <template v-else-if="config.featureType === 'Polygon'">
  58. <div class="__hover" :class="{active: polygonType === 'Polygon'}" @click="reDrawPolygonType('Polygon')"><SvgIcon name="poly_1" size="28" color="#ffffff"/></div>
  59. <div class="__hover" :class="{active: polygonType === 'Rectangle'}" @click="reDrawPolygonType('Rectangle')"><SvgIcon name="rectangle_1" size="28" color="#ffffff"/></div>
  60. <div class="__hover" :class="{active: polygonType === 'Circle'}" @click="reDrawPolygonType('Circle')"><SvgIcon name="circle_1" size="28" color="#ffffff"/></div>
  61. </template>
  62. </div>
  63. </template>
  64. </CusFormColumn>
  65. <template v-if="config.featureType === 'LineString'">
  66. <CusFormColumn
  67. required
  68. :span="24"
  69. label="边线颜色:"
  70. v-model:param="config.lineColor"
  71. :clearable="false"
  72. :readonly="true"
  73. >
  74. <template #suffix>
  75. <el-color-picker v-model="config.lineColor" show-alpha size="small" @change="onConfigChange"/>
  76. </template>
  77. </CusFormColumn>
  78. <CusFormColumn
  79. required
  80. :span="12"
  81. label="边线宽度:"
  82. link="input-number"
  83. v-model:param="config.lineWidth"
  84. unit="像素"
  85. @change="onConfigChange"
  86. :min="1"
  87. />
  88. <CusFormColumn
  89. required
  90. label-width="94px"
  91. :span="12"
  92. label="边线类型:"
  93. link="select"
  94. v-model:param="config.lineType"
  95. static
  96. @change="onConfigChange"
  97. >
  98. <el-option label="—————" :value="0"/>
  99. <el-option label="— — — —" :value="1"/>
  100. <el-option label="- - - - - - - -" :value="2"/>
  101. </CusFormColumn>
  102. </template>
  103. <template v-else-if="config.featureType === 'Polygon'">
  104. <CusFormColumn
  105. required
  106. :span="24"
  107. label="边线颜色:"
  108. v-model:param="config.polyBorderColor"
  109. :clearable="false"
  110. :readonly="true"
  111. >
  112. <template #suffix>
  113. <el-color-picker v-model="config.polyBorderColor" show-alpha size="small" @change="onConfigChange"/>
  114. </template>
  115. </CusFormColumn>
  116. <CusFormColumn
  117. required
  118. :span="12"
  119. label="边线宽度:"
  120. link="input-number"
  121. v-model:param="config.polyBorderWidth"
  122. unit="像素"
  123. @change="onConfigChange"
  124. :min="1"
  125. />
  126. <CusFormColumn
  127. required
  128. :span="12"
  129. label="填充颜色:"
  130. v-model:param="config.polyColor"
  131. :clearable="false"
  132. :readonly="true"
  133. >
  134. <template #suffix>
  135. <el-color-picker v-model="config.polyColor" show-alpha size="small" @change="onConfigChange"/>
  136. </template>
  137. </CusFormColumn>
  138. </template>
  139. </CusForm>
  140. <div class="position-handle">
  141. <div class="ph-tabs" v-if="config.featureType === 'Polygon'">
  142. <div class="__hover" :class="{active: typeTab === 'default'}" @click="operationTab = 'draw', typeTab = 'default'">要素标绘</div>
  143. <template v-if="config.wkt">
  144. <div v-if="config.isHcq" class="__hover" :class="{active: typeTab === 'hcq'}" @click="operationTab = 'draw', typeTab = 'hcq'">缓冲区标绘</div>
  145. <div v-if="config.isSmall" class="__hover" :class="{active: typeTab === 'small'}" @click="operationTab = 'draw', typeTab = 'small'">缩略点标绘</div>
  146. </template>
  147. </div>
  148. <template v-if="typeTab === 'hcq'">
  149. <div class="hcq-type">
  150. <div class="__hover" @click="hcqType = 'auto'"><div class="__check" :class="{active: hcqType === 'auto'}"/>生成</div>
  151. <div class="__hover" @click="operationTab = 'draw', hcqType = 'cus'"><div class="__check" :class="{active: hcqType === 'cus'}"/>手动标绘</div>
  152. </div>
  153. </template>
  154. <div class="ph-operation-tabs" v-if="!(typeTab === 'hcq' && hcqType === 'auto')">
  155. <div class="__hover" :class="{active: operationTab === 'draw'}" @click="operationTab = 'draw'">拖动</div>
  156. <div v-if="isFeatureValid" class="__hover" :class="{active: operationTab === 'position'}" @click="operationTab = 'position'">坐标</div>
  157. <div class="__hover" :class="{active: operationTab === 'text'}" @click="operationTab = 'text'">文本</div>
  158. </div>
  159. <template v-if="typeTab === 'default'">
  160. <template v-if="operationTab === 'draw'">
  161. <template v-if="polygonType === 'Rectangle'">
  162. <div class="redraw">
  163. <div class="__hover" @click="reDrawRectangle">重绘</div>
  164. </div>
  165. </template>
  166. <template v-if="polygonType === 'Circle'">
  167. <div class="redraw">
  168. <div class="__hover" @click="reDrawCircle">重绘</div>
  169. <div class="__hover" @click="circleToPolygon" v-if="circleReady">生成圆</div>
  170. </div>
  171. </template>
  172. <div class="draw-tips">
  173. * 可在地图上,通过以下操作调整图形:<br/>
  174. <template v-if="config.featureType === 'Point'">
  175. 1、拖动坐标点位置可调整点的位置;<br/>
  176. </template>
  177. <template v-else-if="config.featureType === 'LineString'">
  178. 1、拖动调整坐标点位置;<br/>
  179. 2、删除坐标点请切换到坐标页签操作;<br/>
  180. 3、点击边线即可增加坐标点;<br/>
  181. </template>
  182. <template v-else-if="config.featureType === 'Polygon'">
  183. <template v-if="polygonType === 'Polygon'">
  184. 1、拖动调整坐标点位置;<br/>
  185. 2、删除坐标点请切换到坐标页签操作;<br/>
  186. 3、点击边线即可增加坐标点;<br/>
  187. </template>
  188. <template v-else-if="polygonType === 'Rectangle'">
  189. 1、点击地图,拖动鼠标可重新标绘;<br/>
  190. </template>
  191. <template v-else-if="polygonType === 'Circle'">
  192. 1、拖动边线坐标点位置或者修改坐标中的半径值可调整圆形的半径大小;<br/>
  193. 2、拖动圆心或者修改坐标中的圆心坐标点的值可调整圆形的位置;<br/>
  194. </template>
  195. </template>
  196. </div>
  197. </template>
  198. <template v-else-if="operationTab === 'position'">
  199. <PositionList v-model:wkt="config.wkt" :isView="config.featureType === 'Point' || (config.featureType === 'Polygon' && ['Rectangle', 'Circle'].includes(polygonType))" @toPosition="onToPosition"/>
  200. </template>
  201. <template v-else-if="operationTab === 'text'">
  202. <div class="textarea-block">
  203. <template v-if="config.featureType === 'Point'">
  204. <div class="tips">
  205. 输入经纬度,样例:<br/>
  206. POINT(109.1 20.5)
  207. </div>
  208. <CusFormColumn
  209. ref="ref_wktTextarea"
  210. class="wkt-textarea"
  211. :span="24"
  212. required
  213. type="textarea"
  214. v-model:param="config.wkt"
  215. default-error-msg="请输入点位坐标"
  216. :rules="[
  217. {
  218. handle: (val) => $easyMap.validWkt.Point(val),
  219. message: '点位WKT坐标格式错误'
  220. }
  221. ]"
  222. />
  223. </template>
  224. <template v-if="config.featureType === 'LineString'">
  225. <div class="tips">
  226. 输入经纬度,样例:<br/>
  227. LINESTRING(109.2 19.5,109.6 19.1,110.2 19.4)
  228. </div>
  229. <CusFormColumn
  230. ref="ref_wktTextarea"
  231. class="wkt-textarea"
  232. :span="24"
  233. required
  234. type="textarea"
  235. v-model:param="config.wkt"
  236. default-error-msg="请输入线坐标"
  237. :rules="[
  238. {
  239. handle: (val) => $easyMap.validWkt.LineString(val),
  240. message: '线段WKT坐标格式错误'
  241. },
  242. ]"
  243. />
  244. </template>
  245. <template v-else-if="config.featureType === 'Polygon'">
  246. <div class="tips">
  247. 输入经纬度(首尾坐标需要一致),样例:<br/>
  248. POLYGON((109.7 19.3,109.5 19.1,109.8 19.1,109.7 19.3))
  249. </div>
  250. <CusFormColumn
  251. ref="ref_wktTextarea"
  252. class="wkt-textarea"
  253. :span="24"
  254. required
  255. type="textarea"
  256. v-model:param="config.wkt"
  257. :disabled="['Rectangle', 'Circle'].includes(polygonType)"
  258. default-error-msg="请输入区域坐标"
  259. :rules="[
  260. {
  261. handle: (val) => $easyMap.validWkt.Polygon(val),
  262. message: '区域WKT坐标格式错误'
  263. },
  264. {
  265. handle: (val) => $easyMap.validWkt.PolygonKinks(val),
  266. message: '区域坐标不可自相交'
  267. },
  268. ]"
  269. />
  270. </template>
  271. </div>
  272. </template>
  273. </template>
  274. <template v-else-if="typeTab === 'hcq'">
  275. <template v-if="hcqType === 'auto'">
  276. <div class="hcq-radius">
  277. <el-slider v-model="config.hcqAutoRadius" :step="0.001" :max="1" :min="0.001" @input="initDrawHcq" show-input/>km
  278. </div>
  279. </template>
  280. <template v-else>
  281. <template v-if="operationTab === 'draw'">
  282. <div class="draw-tips">
  283. * 可在地图上,通过以下操作调整图形:<br/>
  284. 1、拖动调整坐标点位置;<br/>
  285. 2、删除坐标点请切换到坐标页签操作;<br/>
  286. 3、点击边线即可增加坐标点;<br/>
  287. </div>
  288. </template>
  289. <template v-else-if="operationTab === 'position'">
  290. <PositionList v-model:wkt="config.hcqWkt" @toPosition="onToPosition"/>
  291. </template>
  292. <template v-else-if="operationTab === 'text'">
  293. <div class="textarea-block">
  294. <div class="tips">
  295. 输入经纬度(首尾坐标需要一致),样例:<br/>
  296. POLYGON((109.7 19.3,109.5 19.1,109.8 19.1,109.7 19.3))
  297. </div>
  298. <CusFormColumn
  299. ref="ref_wktTextarea"
  300. class="wkt-textarea"
  301. :span="24"
  302. required
  303. type="textarea"
  304. v-model:param="config.hcqWkt"
  305. default-error-msg="请输入区域坐标"
  306. :rules="[
  307. {
  308. handle: (val) => $easyMap.validWkt.Polygon(val),
  309. message: '区域WKT坐标格式错误'
  310. },
  311. {
  312. handle: (val) => $easyMap.validWkt.PolygonKinks(val),
  313. message: '区域坐标不可自相交'
  314. },
  315. {
  316. handle: (val) => $easyMap.validWkt.PolygonBooleanContains(val, config.wkt),
  317. message: '缓冲区需全包含区域'
  318. },
  319. ]"
  320. />
  321. </div>
  322. </template>
  323. </template>
  324. </template>
  325. <template v-else-if="typeTab === 'small'">
  326. <template v-if="operationTab === 'draw'">
  327. <div class="draw-tips">
  328. * 可在地图上,通过以下操作调整图形:<br/>
  329. 1、拖动坐标点位置可调整点的位置;<br/>
  330. </div>
  331. </template>
  332. <template v-else-if="operationTab === 'position'">
  333. <PositionList v-model:wkt="config.smallWkt" :isView="true" @toPosition="onToPosition"/>
  334. </template>
  335. <template v-else-if="operationTab === 'text'">
  336. <div class="textarea-block">
  337. <div class="tips">
  338. 输入经纬度,样例:<br/>
  339. POINT(109.1 20.5)
  340. </div>
  341. <CusFormColumn
  342. ref="ref_wktTextarea"
  343. class="wkt-textarea"
  344. :span="24"
  345. required
  346. type="textarea"
  347. v-model:param="config.smallWkt"
  348. default-error-msg="请输入点位坐标"
  349. :rules="[
  350. {
  351. handle: (val) => $easyMap.validWkt.Point(val),
  352. message: '点位WKT坐标格式错误'
  353. },
  354. {
  355. handle: (val) => $easyMap.validWkt.PointInPolygon(val, config.wkt),
  356. message: '缩略点需在区域内'
  357. },
  358. ]"
  359. />
  360. </div>
  361. </template>
  362. </template>
  363. </div>
  364. </div>
  365. <div v-show="tab === '2'" class="content-info">
  366. <Component
  367. :is="transfer.form.com"
  368. :transfer="transfer.form.detail"
  369. v-model:loading="loading"
  370. :isView="config.isView"
  371. :map="map"
  372. ref="ref_formCom"
  373. @pass="(e) => { onClose(); $emit('formDrawClose', {source: 'formDraw', ...e, value: true})}"
  374. @drawDefault="onDrawDefault"
  375. @drawHcq="onDrawHcq"
  376. @drawSmall="onDrawSmall"
  377. @wkt="val => config.wkt = val"
  378. @hcqWkt="val => config.hcqWkt = val"
  379. @smallWkt="val => config.smallWkt = val"
  380. />
  381. </div>
  382. </div>
  383. <div class="bottom-buttons">
  384. <div class="submit __hover" @click="onSubmit">保存</div>
  385. <div class="cancel __hover" @click="onClose(), $emit('formDrawClose', {source: 'formDraw', value: false})">取消</div>
  386. </div>
  387. </template>
  388. </div>
  389. </ToolsDialog>
  390. </template>
  391. <script lang="ts">
  392. import {
  393. defineComponent,
  394. onMounted,
  395. ref,
  396. toRefs,
  397. reactive,
  398. watch,
  399. getCurrentInstance,
  400. ComponentInternalInstance,
  401. computed, nextTick
  402. } from "vue";
  403. import ToolsDialog from '../tools-dialog.vue'
  404. import * as Handle from './handle'
  405. import PositionList from "./position-list.vue";
  406. import * as layer from "ol/layer";
  407. import * as source from "ol/source";
  408. import * as format from "ol/format";
  409. import * as style from "ol/style";
  410. import * as turf from "@turf/turf";
  411. import {ElMessage, ElMessageBox} from "element-plus";
  412. export default defineComponent({
  413. name: "",
  414. components: {
  415. ToolsDialog,
  416. PositionList
  417. },
  418. props: {
  419. transfer: {},
  420. show: {required: true},
  421. map: {required: true},
  422. mapFuncToLocation: {required: true},
  423. mapHeight: {},
  424. mapWidth: {},
  425. layout: {},
  426. },
  427. setup(props, { emit }) {
  428. const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties;
  429. const state = reactive({
  430. toolsLayout: {
  431. width: 478,
  432. left: 10,
  433. top: 10
  434. },
  435. tab: '1',
  436. typeTab: 'default',
  437. operationTab: 'draw',
  438. hcqType: 'auto',
  439. config: {},
  440. loading: false,
  441. staticLayer: <any>null,
  442. refreshStyleFunc: <any>null,
  443. isFeatureValid: false,
  444. staticSmallLayer: <any>null,
  445. staticHcqLayer: <any>null,
  446. circleReady: false,
  447. circleWkt: '',
  448. isInit: false,
  449. isWaitWkt: false,
  450. polygonType: ''
  451. });
  452. const ref_formCom = ref()
  453. const ref_drawForm = ref()
  454. const ref_wktTextarea = ref()
  455. watch(() => props.show, (n: any) => {
  456. if (n) {
  457. if (!state.config.isView) {
  458. state.isWaitWkt = !props.transfer.config.wkt
  459. }
  460. state.config = props.transfer?.config
  461. console.log(JSON.parse(JSON.stringify(state.config)))
  462. state.polygonType = state.config.featureType === 'Polygon' ? 'Polygon' : ''
  463. initHandle()
  464. }
  465. })
  466. const initHandle = () => {
  467. state.tab = '1'
  468. state.typeTab = 'default'
  469. if (that.$util.isValue(state.config.hcqAuto)) {
  470. state.hcqType = state.config.hcqAuto ? 'auto' : 'cus'
  471. } else {
  472. state.hcqType = 'auto'
  473. }
  474. state.operationTab = 'draw'
  475. if (!state.config.hcqAutoRadius) {
  476. state.config.hcqAutoRadius = 0.05
  477. }
  478. if (!state.config.isView) {
  479. initDrawDefault()
  480. } else {
  481. initStaticLayer(true)
  482. if (state.config.isHcq) {
  483. initStaticHcqLayer(false)
  484. }
  485. if (state.config.isSmall) {
  486. initStaticSmallLayer(false)
  487. }
  488. }
  489. setTimeout(() => {
  490. state.isInit = true
  491. }, 100)
  492. }
  493. const onDrawDefault = () => {
  494. state.tab = '1'
  495. state.typeTab = 'default'
  496. state.operationTab = 'draw'
  497. }
  498. const onDrawHcq = () => {
  499. state.tab = '1'
  500. state.typeTab = 'hcq'
  501. state.operationTab = 'draw'
  502. }
  503. const onDrawSmall = () => {
  504. state.tab = '1'
  505. state.typeTab = 'small'
  506. state.operationTab = 'draw'
  507. }
  508. const drawDefaultSuccess = () => {
  509. const obj = {
  510. featureType: state.config.featureType,
  511. polygonType: state.polygonType,
  512. wkt: state.config.wkt,
  513. }
  514. switch (obj.featureType) {
  515. case 'Point': {} break
  516. case 'LineString': {
  517. obj.lineColor = state.config.lineColor
  518. obj.lineWidth = state.config.lineWidth
  519. obj.lineType = state.config.lineType
  520. } break
  521. default: {
  522. obj.polyColor = state.config.polyColor
  523. obj.polyBorderColor = state.config.polyBorderColor
  524. obj.polyBorderWidth = state.config.polyBorderWidth
  525. obj.polyBorderType = state.config.polyBorderType
  526. }
  527. }
  528. ref_formCom.value?.setDefault(obj)
  529. }
  530. const drawSmallSuccess = () => {
  531. if (state.config.isSmall) {
  532. const obj = {
  533. smallWkt: state.config.smallWkt
  534. }
  535. ref_formCom.value?.setSmall(obj)
  536. }
  537. }
  538. const drawHcqSuccess = () => {
  539. if (state.config.isHcq) {
  540. const obj = {
  541. hcqWkt: state.config.hcqWkt,
  542. hcqAuto: state.config.hcqAuto,
  543. hcqAutoRadius: state.config.hcqAutoRadius,
  544. hcqPolyColor: state.config.hcqPolyColor,
  545. hcqPolyBorderColor: state.config.hcqPolyBorderColor
  546. }
  547. ref_formCom.value?.setHcq(obj)
  548. }
  549. }
  550. const initDrawDefault = () => {
  551. state.staticLayer?.getSource()?.clear()
  552. Handle.formDrawExit(props.map)
  553. if (!(state.config.featureType === 'Polygon' && ['Rectangle', 'Circle'].includes(state.polygonType))) {
  554. Handle.formDrawHandle({
  555. map: props.map,
  556. config: state.config,
  557. emitWkt: (wkt) => {
  558. state.isWaitWkt = false
  559. state.config.wkt = wkt
  560. let position = []
  561. switch (state.config.featureType) {
  562. case 'Point': {
  563. position = [that.$easyMap.formatPosition.wptTcpt(state.config.wkt)]
  564. } break
  565. case 'LineString': {
  566. position = that.$easyMap.formatPosition.wlTcl(state.config.wkt)
  567. } break
  568. case 'Polygon': {
  569. position = that.$easyMap.formatPosition.wpnTcpn(state.config.wkt)[0]
  570. } break
  571. }
  572. that.$easyMap.getShapeView(props.map, position)
  573. }
  574. }).then((func: any) => {
  575. state.refreshStyleFunc = () => {
  576. func()
  577. drawDefaultSuccess()
  578. if (state.config.featureType === 'Polygon') {
  579. let _s: any = [
  580. new style.Style({
  581. stroke: new style.Stroke({
  582. color: state.config.hcqPolyBorderColor,
  583. width: 1,
  584. }),
  585. fill: new style.Fill({
  586. color: state.config.hcqPolyColor,
  587. }),
  588. })
  589. ]
  590. state.staticHcqLayer?.setStyle(_s)
  591. }
  592. }
  593. drawDefaultSuccess()
  594. })
  595. } else {
  596. if (state.config.wkt) {
  597. initStaticLayer(true)
  598. } else {
  599. if (state.config.featureType === 'Polygon' && state.polygonType === 'Rectangle') {
  600. reDrawRectangle()
  601. } else if (state.config.featureType === 'Polygon' && state.polygonType === 'Circle') {
  602. reDrawCircle()
  603. }
  604. }
  605. }
  606. if (state.config.featureType === 'Polygon') {
  607. initStaticHcqLayer(false)
  608. initStaticSmallLayer(false)
  609. }
  610. }
  611. const reDrawRectangle = () => {
  612. state.config.wkt = ''
  613. const conf = {
  614. ...state.config,
  615. featureType: 'Rectangle'
  616. }
  617. Handle.formDrawHandle({
  618. map: props.map,
  619. config: conf,
  620. emitWkt: (wkt) => {
  621. state.isWaitWkt = false
  622. state.config.wkt = wkt
  623. Handle.formDrawExit(props.map)
  624. drawDefaultSuccess()
  625. initStaticLayer(true)
  626. }
  627. }).then((func: any) => {
  628. state.refreshStyleFunc = () => {
  629. func()
  630. drawDefaultSuccess()
  631. let _s: any = [
  632. new style.Style({
  633. stroke: new style.Stroke({
  634. color: state.config.hcqPolyBorderColor,
  635. width: 1,
  636. }),
  637. fill: new style.Fill({
  638. color: state.config.hcqPolyColor,
  639. }),
  640. })
  641. ]
  642. state.staticHcqLayer?.setStyle(_s)
  643. }
  644. drawDefaultSuccess()
  645. })
  646. }
  647. const reDrawCircle = () => {
  648. state.circleReady = false
  649. state.config.wkt = ''
  650. const conf = {
  651. ...state.config,
  652. circleToPolygon: false,
  653. featureType: 'Circle'
  654. }
  655. Handle.formDrawHandle({
  656. map: props.map,
  657. config: conf,
  658. emitWkt: (wkt) => {
  659. state.circleReady = true
  660. state.circleWkt = wkt
  661. }
  662. }).then((func: any) => {
  663. state.refreshStyleFunc = () => {
  664. func()
  665. drawDefaultSuccess()
  666. let _s: any = [
  667. new style.Style({
  668. stroke: new style.Stroke({
  669. color: state.config.hcqPolyBorderColor,
  670. width: 1,
  671. }),
  672. fill: new style.Fill({
  673. color: state.config.hcqPolyColor,
  674. }),
  675. })
  676. ]
  677. state.staticHcqLayer?.setStyle(_s)
  678. }
  679. drawDefaultSuccess()
  680. })
  681. }
  682. const circleToPolygon = () => {
  683. state.config.wkt = state.circleWkt
  684. Handle.formDrawExit(props.map)
  685. drawDefaultSuccess()
  686. initStaticLayer(true)
  687. state.circleReady = false
  688. }
  689. const initDrawSmall = () => {
  690. if (state.config.isSmall) {
  691. state.staticSmallLayer?.getSource()?.clear()
  692. Handle.formDrawExit(props.map)
  693. Handle.formDrawHandle({
  694. map: props.map,
  695. config: {
  696. featureType: 'Point',
  697. wkt: state.config.smallWkt,
  698. pointIcon: state.config.smallIcon,
  699. pointScale: state.config.smallScale,
  700. },
  701. emitWkt: (wkt) => {
  702. state.config.smallWkt = wkt
  703. }
  704. }).then((func: any) => {
  705. drawSmallSuccess()
  706. })
  707. initStaticLayer(false)
  708. initStaticHcqLayer(false)
  709. }
  710. }
  711. const initDrawHcq = async () => {
  712. if (state.config.isHcq) {
  713. state.staticHcqLayer?.getSource().clear()
  714. if (state.hcqType === 'cus') {
  715. setTimeout(() => {
  716. state.staticHcqLayer?.getSource().clear()
  717. }, 1000)
  718. Handle.formDrawExit(props.map)
  719. Handle.formDrawHandle({
  720. map: props.map,
  721. config: {
  722. featureType: 'Polygon',
  723. wkt: state.config.hcqWkt,
  724. polyColor: state.config.hcqPolyColor,
  725. polyBorderColor: state.config.hcqPolyBorderColor,
  726. },
  727. emitWkt: (wkt) => {
  728. state.config.hcqWkt = wkt
  729. }
  730. }).then((func: any) => {
  731. state.refreshStyleFunc = () => {
  732. func()
  733. drawHcqSuccess()
  734. }
  735. drawHcqSuccess()
  736. })
  737. } else {
  738. drawHcqSuccess()
  739. Handle.formDrawExit(props.map)
  740. await setHcq()
  741. initStaticHcqLayer(true)
  742. }
  743. initStaticLayer(false)
  744. initStaticSmallLayer(false)
  745. }
  746. }
  747. const setHcq = () => {
  748. if (state.config.featureType === 'Polygon' && state.hcqType === 'auto' && state.config.isHcq) {
  749. const porCoordinates = that.$easyMap.formatPosition.wpnTcpn(state.config.wkt)
  750. let hcq = turf.buffer(turf.polygon(porCoordinates), state.config.hcqAutoRadius, {units: 'kilometers'})
  751. if (!hcq) {
  752. ElMessageBox.confirm('当前距离无法生成缓冲区,是否设置为极限值?', '提示', {
  753. confirmButtonText: '确定',
  754. cancelButtonText: '取消',
  755. type: 'warning'
  756. }).then(() => {
  757. let _val = state.config.hcqAutoRadius
  758. do {
  759. hcq = turf.buffer(turf.polygon(porCoordinates), _val += 0.01, {units: 'kilometers'})
  760. } while (!hcq)
  761. state.config.hcqAutoRadius = Number(_val.toFixed(2))
  762. setHcq()
  763. }).catch(() => {
  764. return
  765. })
  766. }
  767. state.config.hcqWkt = that.$easyMap.formatPosition.cpnTwpn(hcq.geometry.coordinates)
  768. }
  769. }
  770. const setSmall = () => {
  771. if (state.config.featureType === 'Polygon' && state.config.isSmall && state.isInit) {
  772. try {
  773. const feat: any = new format.WKT().readFeature(state.config.wkt)
  774. state.config.smallWkt = that.$easyMap.formatPosition.cptTwpt(feat.getGeometry().getInteriorPoint().getCoordinates())
  775. } catch (e) {
  776. state.config.smallWkt = ''
  777. }
  778. }
  779. }
  780. const onToPosition = (coor) => {
  781. props.mapFuncToLocation({position: coor})
  782. }
  783. const onClose = () => {
  784. Handle.formDrawExit(props.map)
  785. if (state.staticLayer) {
  786. props.map.removeLayer(state.staticLayer)
  787. state.staticLayer = null
  788. }
  789. if (state.staticHcqLayer) {
  790. props.map.removeLayer(state.staticHcqLayer)
  791. state.staticHcqLayer = null
  792. }
  793. if (state.staticSmallLayer) {
  794. props.map.removeLayer(state.staticSmallLayer)
  795. state.staticSmallLayer = null
  796. }
  797. emit('update:show', false)
  798. state.isInit = false
  799. }
  800. const initStaticLayer = (auto = true) => {
  801. if (
  802. state.config.featureType === 'Point' && that.$easyMap.validWkt.Point(state.config.wkt) ||
  803. state.config.featureType === 'LineString' && that.$easyMap.validWkt.LineString(state.config.wkt) ||
  804. state.config.featureType === 'Polygon' && that.$easyMap.validWkt.Polygon(state.config.wkt)
  805. ) {
  806. let _s: any = []
  807. switch (state.config.featureType) {
  808. case 'Point': {
  809. _s.push(new style.Style({
  810. image: new style.Icon({
  811. src: state.config.pointIcon,
  812. scale: state.config.pointScale
  813. })
  814. }))
  815. } break
  816. case 'LineString': {
  817. _s.push(new style.Style({
  818. stroke: new style.Stroke({
  819. color: state.config.lineColor,
  820. width: state.config.lineWidth,
  821. lineDash: Handle.globalLineDash[Number(state.config.lineType)]
  822. }),
  823. }))
  824. } break
  825. default: {
  826. _s.push(new style.Style({
  827. stroke: new style.Stroke({
  828. color: state.config.polyBorderColor,
  829. width: state.config.polyBorderWidth,
  830. lineDash: Handle.globalLineDash[Number(state.config.polyBorderType)]
  831. }),
  832. fill: new style.Fill({
  833. color: state.config.polyColor,
  834. }),
  835. }))
  836. }
  837. }
  838. if (!state.staticLayer) {
  839. state.staticLayer = new layer.Vector({
  840. zIndex: 9997,
  841. })
  842. props.map.addLayer(state.staticLayer)
  843. }
  844. try {
  845. state.staticLayer?.setStyle(_s)
  846. const f: any = new format.WKT().readFeature(state.config.wkt)
  847. state.staticLayer?.setSource(new source.Vector({
  848. features: [f]
  849. }))
  850. if (auto) {
  851. switch (f.getGeometry().getType()) {
  852. case 'Point': {
  853. Handle.getShapeView(props.map, [f.getGeometry().getCoordinates()])
  854. } break
  855. case 'LineString': {
  856. Handle.getShapeView(props.map, f.getGeometry().getCoordinates())
  857. } break
  858. case 'Polygon': {
  859. Handle.getShapeView(props.map, f.getGeometry().getCoordinates()[0])
  860. } break
  861. }
  862. }
  863. } catch (e) {
  864. state.staticLayer?.getSource()?.clear()
  865. }
  866. if (state.config.featureType === 'Polygon' && state.hcqType === 'auto') {
  867. initStaticHcqLayer(false)
  868. }
  869. }
  870. }
  871. const initStaticSmallLayer = (auto = true) => {
  872. if (state.config.isSmall) {
  873. if (that.$easyMap.validWkt.Point(state.config.smallWkt)) {
  874. let _s: any = [
  875. new style.Style({
  876. image: new style.Icon({
  877. src: state.config.smallIcon,
  878. scale: state.config.smallScale
  879. })
  880. })
  881. ]
  882. if (!state.staticSmallLayer) {
  883. state.staticSmallLayer = new layer.Vector({
  884. zIndex: 10000,
  885. })
  886. props.map.addLayer(state.staticSmallLayer)
  887. }
  888. try {
  889. state.staticSmallLayer?.setStyle(_s)
  890. const f: any = new format.WKT().readFeature(state.config.smallWkt)
  891. state.staticSmallLayer?.setSource(new source.Vector({
  892. features: [f]
  893. }))
  894. if (auto) {
  895. Handle.getShapeView(props.map, [f.getGeometry().getCoordinates()])
  896. }
  897. } catch (e) {
  898. state.staticSmallLayer?.getSource()?.clear()
  899. }
  900. }
  901. }
  902. }
  903. const initStaticHcqLayer = (auto = true) => {
  904. if (state.config.isHcq) {
  905. if (that.$easyMap.validWkt.Polygon(state.config.hcqWkt)) {
  906. let _s: any = [
  907. new style.Style({
  908. stroke: new style.Stroke({
  909. color: state.config.hcqPolyBorderColor,
  910. width: 1,
  911. }),
  912. fill: new style.Fill({
  913. color: state.config.hcqPolyColor,
  914. }),
  915. })
  916. ]
  917. if (!state.staticHcqLayer) {
  918. state.staticHcqLayer = new layer.Vector({
  919. zIndex: 9996,
  920. })
  921. props.map.addLayer(state.staticHcqLayer)
  922. }
  923. try {
  924. state.staticHcqLayer?.setStyle(_s)
  925. const f: any = new format.WKT().readFeature(state.config.hcqWkt)
  926. state.staticHcqLayer?.setSource(new source.Vector({
  927. features: [f]
  928. }))
  929. if (auto) {
  930. Handle.getShapeView(props.map, f.getGeometry().getCoordinates()[0])
  931. }
  932. } catch (e) {
  933. state.staticHcqLayer?.getSource()?.clear()
  934. }
  935. }
  936. }
  937. }
  938. const onConfigChange = () => {
  939. nextTick(() => {
  940. if (state.operationTab !== 'draw') {
  941. initStaticLayer(false)
  942. } else {
  943. state.refreshStyleFunc?.()
  944. if (state.typeTab === 'default') {
  945. initStaticHcqLayer(false)
  946. if (state.config.featureType === 'Polygon' && ['Rectangle', 'Circle'].includes(state.polygonType)) {
  947. initStaticLayer(false)
  948. }
  949. } else if (state.typeTab === 'hcq') {
  950. initStaticLayer(false)
  951. } else if (state.typeTab === 'small') {
  952. initStaticLayer(false)
  953. initStaticHcqLayer(false)
  954. }
  955. }
  956. })
  957. }
  958. watch(() => state.operationTab, (n, o) => {
  959. if (n === 'draw') {
  960. if (state.typeTab === 'default') {
  961. initDrawDefault()
  962. } else if (state.typeTab === 'hcq') {
  963. initDrawHcq()
  964. } else if (state.typeTab === 'small') {
  965. initDrawSmall()
  966. }
  967. }
  968. if (o === 'draw') {
  969. Handle.formDrawExit(props.map)
  970. initStaticLayer(false)
  971. if (state.config.featureType === 'Polygon') {
  972. initStaticHcqLayer(false)
  973. initStaticSmallLayer(false)
  974. }
  975. }
  976. if (n === 'text') {
  977. nextTick(() => {
  978. ref_wktTextarea.value?.handleValidate()
  979. })
  980. }
  981. })
  982. watch(() => state.tab, (n) => {
  983. if (n === '1') {
  984. if (!state.config.wkt && state.typeTab !== 'default') {
  985. state.typeTab = 'default'
  986. state.operationTab = 'draw'
  987. }
  988. if (state.operationTab === 'draw') {
  989. if (state.typeTab === 'default') {
  990. initDrawDefault()
  991. } else if (state.typeTab === 'hcq') {
  992. initDrawHcq()
  993. } else if (state.typeTab === 'small') {
  994. initDrawSmall()
  995. }
  996. }
  997. } else {
  998. Handle.formDrawExit(props.map)
  999. // if (state.isFeatureValid) {
  1000. initStaticLayer()
  1001. if (state.config.featureType === 'Polygon') {
  1002. initStaticHcqLayer(false)
  1003. initStaticSmallLayer(false)
  1004. }
  1005. // }
  1006. }
  1007. })
  1008. watch(() => state.config.wkt, async (n, o) => {
  1009. if (n && state.isWaitWkt) {
  1010. initDrawDefault()
  1011. } else {
  1012. try {
  1013. const f: any = new format.WKT().readFeature(n)
  1014. if (f.getGeometry().getType() === 'Polygon' && that.$easyMap.validWkt.Polygon(n)) {
  1015. state.isFeatureValid = true
  1016. } else if (f.getGeometry().getType() === 'LineString' && that.$easyMap.validWkt.LineString(n)) {
  1017. state.isFeatureValid = true
  1018. } else if (f.getGeometry().getType() === 'Point' && that.$easyMap.validWkt.Point(n)) {
  1019. state.isFeatureValid = true
  1020. } else {
  1021. state.isFeatureValid = false
  1022. }
  1023. await setHcq()
  1024. initStaticHcqLayer(false)
  1025. await setSmall()
  1026. initStaticSmallLayer(false)
  1027. } catch (e) {
  1028. state.staticLayer?.getSource()?.clear()
  1029. state.staticHcqLayer?.getSource()?.clear()
  1030. state.staticSmallLayer?.getSource()?.clear()
  1031. state.isFeatureValid = false
  1032. if (state.operationTab === 'position') {
  1033. state.operationTab = 'draw'
  1034. }
  1035. }
  1036. if (state.operationTab !== 'draw' || state.tab === '2') {
  1037. initStaticLayer(false)
  1038. }
  1039. drawDefaultSuccess()
  1040. }
  1041. })
  1042. watch(() => state.config.smallWkt, (n, o) => {
  1043. try {
  1044. const f = new format.WKT().readFeature(n)
  1045. if (that.$easyMap.validWkt.Point(n)) {
  1046. state.isFeatureValid = true
  1047. } else {
  1048. state.isFeatureValid = false
  1049. }
  1050. } catch (e) {
  1051. state.staticSmallLayer?.getSource()?.clear()
  1052. state.isFeatureValid = false
  1053. if (state.operationTab === 'position') {
  1054. state.operationTab = 'draw'
  1055. }
  1056. }
  1057. if (state.operationTab !== 'draw' || state.tab === '2' || !o) {
  1058. initStaticSmallLayer(false)
  1059. }
  1060. drawSmallSuccess()
  1061. })
  1062. watch(() => state.config.hcqWkt, (n, o) => {
  1063. try {
  1064. const f = new format.WKT().readFeature(n)
  1065. if (that.$easyMap.validWkt.Polygon(n)) {
  1066. state.isFeatureValid = true
  1067. } else {
  1068. state.isFeatureValid = false
  1069. }
  1070. } catch (e) {
  1071. state.staticHcqLayer?.getSource()?.clear()
  1072. state.isFeatureValid = false
  1073. if (state.operationTab === 'position') {
  1074. state.operationTab = 'draw'
  1075. }
  1076. }
  1077. if (state.operationTab !== 'draw' || state.tab === '2' || !o) {
  1078. initStaticHcqLayer(false)
  1079. }
  1080. drawHcqSuccess()
  1081. })
  1082. watch(() => state.typeTab, (n) => {
  1083. switch (n) {
  1084. case 'default': {
  1085. initDrawDefault()
  1086. } break
  1087. case 'hcq': {
  1088. initDrawHcq()
  1089. } break
  1090. case 'small': {
  1091. initDrawSmall()
  1092. } break
  1093. }
  1094. })
  1095. watch(() => state.config.polyColor, (n) => {
  1096. if (n && state.isInit) {
  1097. state.config.hcqPolyColor = that.$util.resetRgbaOpacity(state.config.polyColor, 0.3)
  1098. }
  1099. })
  1100. watch(() => state.config.polyBorderColor, (n) => {
  1101. if (n && state.isInit) {
  1102. state.config.hcqPolyBorderColor = that.$util.resetRgbaOpacity(state.config.polyBorderColor, 0.3)
  1103. }
  1104. })
  1105. watch(() => state.hcqType, (n) => {
  1106. state.config.hcqAuto = n === 'auto'
  1107. if (state.isInit) {
  1108. initDrawHcq()
  1109. }
  1110. })
  1111. const onSubmit = () => {
  1112. ref_drawForm.value.submit().then(() => {
  1113. const wktMsg = ref_wktTextarea.value?.handleValidate()
  1114. if (wktMsg) {
  1115. ElMessage({
  1116. message: wktMsg,
  1117. grouping: true,
  1118. type: 'warning',
  1119. })
  1120. state.tab = '1'
  1121. } else {
  1122. ref_formCom.value?.onSubmit()
  1123. state.tab = '2'
  1124. }
  1125. }).catch((e: any) => {
  1126. ElMessage({
  1127. message: e[0].message,
  1128. grouping: true,
  1129. type: 'warning',
  1130. })
  1131. state.tab = '1'
  1132. })
  1133. }
  1134. watch(() => props.layout, (n: any) => {
  1135. state.toolsLayout = {
  1136. width: state.toolsLayout.width,
  1137. top: n.top,
  1138. left: n.left,
  1139. }
  1140. })
  1141. const onEdit = () => {
  1142. state.config.isView = false
  1143. initHandle()
  1144. }
  1145. const reDrawPolygonType = (type) => {
  1146. if (state.polygonType !== type) {
  1147. ElMessageBox.confirm('切换形状后将清空坐标并重新标绘,是否继续?', '提示', {
  1148. confirmButtonText: '确定',
  1149. cancelButtonText: '取消',
  1150. type: 'warning'
  1151. }).then(() => {
  1152. state.isInit = false
  1153. state.polygonType = type
  1154. state.config.wkt = ''
  1155. state.config.hcqWkt = ''
  1156. state.config.smallWkt = ''
  1157. state.config.hcqAuto = true
  1158. state.config.hcqAutoRadius = 0
  1159. initHandle()
  1160. }).catch(() => {
  1161. return
  1162. })
  1163. }
  1164. }
  1165. return {
  1166. ...toRefs(state),
  1167. ref_formCom,
  1168. ref_drawForm,
  1169. ref_wktTextarea,
  1170. onDrawDefault,
  1171. onDrawHcq,
  1172. onDrawSmall,
  1173. drawDefaultSuccess,
  1174. drawSmallSuccess,
  1175. drawHcqSuccess,
  1176. onToPosition,
  1177. onClose,
  1178. initStaticLayer,
  1179. onConfigChange,
  1180. initDrawHcq,
  1181. reDrawRectangle,
  1182. reDrawCircle,
  1183. circleToPolygon,
  1184. onSubmit,
  1185. onEdit,
  1186. reDrawPolygonType,
  1187. }
  1188. },
  1189. });
  1190. </script>
  1191. <style scoped lang="scss">
  1192. $mapHeight: var(--easy-map-height);
  1193. .base-draw-com {
  1194. height: calc($mapHeight - 40px - 20px);
  1195. border-bottom: 1px solid #FFFFFF;
  1196. position: relative;
  1197. display: flex;
  1198. flex-direction: column;
  1199. .base-draw-com-tabs {
  1200. display: flex;
  1201. height: 30px;
  1202. margin: 10px;
  1203. >div {
  1204. flex: 1;
  1205. background-color: rgba(0,98,233,0.35);
  1206. display: flex;
  1207. align-items: center;
  1208. justify-content: center;
  1209. font-family: PingFang SC, PingFang SC;
  1210. font-weight: 400;
  1211. font-size: 14px;
  1212. color: #FFFFFF;
  1213. &.active {
  1214. background-color: #0062E9;
  1215. }
  1216. &:first-child {
  1217. clip-path: polygon(0 0, calc(100% - 15px) 0, 100% 50%, calc(100% - 15px) 100%, 0 100%);
  1218. }
  1219. &:last-child {
  1220. clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 15px 50%);
  1221. }
  1222. }
  1223. }
  1224. .content {
  1225. flex: 1;
  1226. overflow-y: auto;
  1227. padding: 10px;
  1228. :deep(.__title) {
  1229. font-family: PingFang SC, PingFang SC;
  1230. font-weight: 500;
  1231. font-size: 14px;
  1232. color: #68C3FF;
  1233. display: flex;
  1234. align-items: center;
  1235. &:before {
  1236. content: '';
  1237. width: 2px;
  1238. height: 16px;
  1239. background-color: #68C3FF;
  1240. margin-right: 7px;
  1241. }
  1242. }
  1243. :deep(.__draw-handle) {
  1244. display: flex;
  1245. gap: 4px;
  1246. margin-left: 100px;
  1247. margin-bottom: 8px;
  1248. >div {
  1249. display: flex;
  1250. align-items: center;
  1251. justify-content: center;
  1252. width: 40px;
  1253. height: 18px;
  1254. background-color: rgba(0,98,233,0.2);
  1255. border-radius: 2px;
  1256. border: 1px solid #0062E9;
  1257. font-family: PingFang SC, PingFang SC;
  1258. font-weight: 400;
  1259. font-size: 10px;
  1260. color: #FFFFFF;
  1261. &.__draw {
  1262. background-color: #0062E9;
  1263. }
  1264. }
  1265. }
  1266. :deep(.cus-form-column) {
  1267. &.__textarea-content {
  1268. .el-form-item {
  1269. margin-bottom: 4px !important;
  1270. }
  1271. }
  1272. .el-form-item {
  1273. margin-bottom: 8px !important;
  1274. &.is-error {
  1275. margin-bottom: 18px !important;
  1276. }
  1277. .el-checkbox{
  1278. color: white;
  1279. }
  1280. .el-checkbox__inner{
  1281. background-color: transparent;
  1282. }
  1283. .el-tag.el-tag--info {
  1284. background: transparent;
  1285. color: white;
  1286. border-color: #1A56D4;
  1287. }
  1288. .el-select__input{
  1289. color: white;
  1290. }
  1291. &.link_input, &.link_select, &.link_date, &.link_date_daterange, &.link_datetime, &.link_datetimerange, &.link_input-number {
  1292. height: 28px;
  1293. .el-form-item__label {
  1294. height: 28px;
  1295. &:before {
  1296. margin-right: 0;
  1297. }
  1298. }
  1299. .el-form-item__content {
  1300. .el-select__wrapper, .el-input__wrapper {
  1301. height: 28px;
  1302. min-height: 28px;
  1303. }
  1304. }
  1305. }
  1306. &.link_input {
  1307. .__draw-handle {
  1308. margin: 0 0 0 4px !important;
  1309. }
  1310. }
  1311. .el-form-item__label {
  1312. font-family: PingFang SC, PingFang SC;
  1313. font-weight: 400;
  1314. font-size: 14px;
  1315. color: #FFFFFF;
  1316. padding: 0;
  1317. margin-right: 10px;
  1318. }
  1319. .el-form-item__content {
  1320. .feature-type {
  1321. display: flex;
  1322. align-items: center;
  1323. gap: 16px;
  1324. >div {
  1325. width: 28px;
  1326. height: 28px;
  1327. display: flex;
  1328. align-items: center;
  1329. justify-content: center;
  1330. &.active {
  1331. background-color: #0062E9;
  1332. }
  1333. }
  1334. }
  1335. .unit {
  1336. font-family: PingFang SC, PingFang SC;
  1337. font-weight: 400;
  1338. font-size: 14px;
  1339. color: #FFFFFF;
  1340. }
  1341. .el-textarea__inner, .el-input__wrapper {
  1342. box-shadow: unset;
  1343. border: 1px solid #1A56D4;
  1344. background-color: transparent;
  1345. color: #FFFFFF;
  1346. word-break: break-all;
  1347. .el-input__inner {
  1348. color: #FFFFFF;
  1349. line-height: 1;
  1350. height: 28px;
  1351. }
  1352. }
  1353. .el-select__wrapper {
  1354. box-shadow: unset;
  1355. border: 1px solid #1A56D4;
  1356. background-color: transparent;
  1357. color: #FFFFFF;
  1358. .el-select__selected-item {
  1359. &:not(&.is-transparent) {
  1360. color: #FFFFFF;
  1361. }
  1362. }
  1363. .el-select__placeholder{
  1364. &:not(.is-transparent) {
  1365. color: white;
  1366. }
  1367. }
  1368. }
  1369. .el-date-editor {
  1370. .el-range-input {
  1371. color: #FFFFFF;
  1372. flex: 1;
  1373. }
  1374. .el-range-separator {
  1375. width: 20px;
  1376. flex: unset;
  1377. }
  1378. }
  1379. .el-color-picker {
  1380. display: flex;
  1381. align-items: center;
  1382. justify-content: center;
  1383. .el-color-picker__trigger {
  1384. width: 14px;
  1385. height: 14px;
  1386. padding: 0;
  1387. border: none;
  1388. .el-color-picker__color {
  1389. border-color: #EAEBEF;
  1390. .el-icon {
  1391. display: none;
  1392. }
  1393. }
  1394. }
  1395. }
  1396. .el-input-number {
  1397. .el-input-number__increase, .el-input-number__decrease {
  1398. background-color: rgba(255, 255, 255, 0.1);
  1399. border: none;
  1400. .el-icon {
  1401. color: rgba(255, 255, 255, 0.6);
  1402. }
  1403. }
  1404. .el-input__inner {
  1405. height: 24px;
  1406. }
  1407. }
  1408. .el-radio-group {
  1409. gap: 10px;
  1410. .el-radio {
  1411. height: 28px;
  1412. margin-right: 0;
  1413. .el-radio__label {
  1414. color: #FFFFFF;
  1415. padding-left: 2px;
  1416. }
  1417. &.is-checked {
  1418. .el-radio__inner {
  1419. background-color: #409eff;
  1420. border-color: #409eff;
  1421. &:after {
  1422. background-color: #f5f7fa;
  1423. }
  1424. }
  1425. }
  1426. }
  1427. }
  1428. .is-disabled {
  1429. .el-select__selected-item:not(.is-transparent),
  1430. .el-input__inner,
  1431. .el-radio__label,
  1432. .el-checkbox__label,
  1433. .el-range-input, .el-range-separator,
  1434. .el-textarea__inner
  1435. {
  1436. color: #FFFFFF;
  1437. -webkit-text-fill-color: #FFFFFF;
  1438. }
  1439. }
  1440. }
  1441. .el-textarea .el-input__count{
  1442. color: #FFFFFF;
  1443. background-color: #102b94;
  1444. }
  1445. }
  1446. }
  1447. .content-draw {
  1448. width: 100%;
  1449. height: 100%;
  1450. display: flex;
  1451. flex-direction: column;
  1452. .position-handle {
  1453. flex: 1;
  1454. display: flex;
  1455. flex-direction: column;
  1456. overflow: hidden;
  1457. .ph-tabs {
  1458. display: flex;
  1459. border-radius: 4px;
  1460. >div {
  1461. display: flex;
  1462. align-items: center;
  1463. justify-content: center;
  1464. padding: 3px 8px;
  1465. font-family: PingFang SC, PingFang SC;
  1466. font-weight: 500;
  1467. font-size: 12px;
  1468. color: #FFFFFF;
  1469. border-top: 1px solid #0062E9;
  1470. border-bottom: 1px solid #0062E9;
  1471. &:first-child {
  1472. border-left: 1px solid #0062E9;
  1473. border-radius: 4px 0 0 4px;
  1474. }
  1475. &:last-child {
  1476. border-right: 1px solid #0062E9;
  1477. border-radius: 0 4px 4px 0;
  1478. }
  1479. &.active {
  1480. background-color: #0062E9;
  1481. }
  1482. }
  1483. }
  1484. .hcq-type {
  1485. margin-top: 10px;
  1486. display: flex;
  1487. align-items: center;
  1488. gap: 10px;
  1489. >div {
  1490. display: flex;
  1491. align-items: center;
  1492. font-family: PingFang SC, PingFang SC;
  1493. font-weight: 400;
  1494. font-size: 14px;
  1495. color: #FFFFFF;
  1496. :deep(.__check) {
  1497. width: 14px;
  1498. height: 14px;
  1499. &:after {
  1500. margin-left: 0;
  1501. }
  1502. }
  1503. }
  1504. }
  1505. .ph-operation-tabs {
  1506. margin-top: 10px;
  1507. display: flex;
  1508. gap: 16px;
  1509. >div {
  1510. display: flex;
  1511. flex-direction: column;
  1512. align-items: center;
  1513. justify-content: center;
  1514. font-family: PingFang SC, PingFang SC;
  1515. font-weight: 500;
  1516. font-size: 14px;
  1517. color: #FFFFFF;
  1518. &:after {
  1519. margin-top: 6px;
  1520. content: '';
  1521. width: 28px;
  1522. height: 3px;
  1523. border-radius: 2px;
  1524. }
  1525. &.active {
  1526. color: #1CFEFF;
  1527. &:after {
  1528. background-color: #1CFEFF;
  1529. }
  1530. }
  1531. }
  1532. }
  1533. .textarea-block {
  1534. flex: 1;
  1535. display: flex;
  1536. flex-direction: column;
  1537. .tips {
  1538. font-family: PingFang SC, PingFang SC;
  1539. font-weight: 400;
  1540. font-size: 14px;
  1541. color: rgba(255,255,255,0.6);
  1542. padding-left: 34px;
  1543. position: relative;
  1544. &:before {
  1545. content: '';
  1546. background-image: url("../../images/tips.png");
  1547. background-repeat: no-repeat;
  1548. background-size: 100% 100%;
  1549. width: 16px;
  1550. height: 16px;
  1551. position: absolute;
  1552. top: 2px;
  1553. left: 10px;
  1554. }
  1555. }
  1556. :deep(.wkt-textarea) {
  1557. flex: 1;
  1558. .el-form-item {
  1559. height: 100%;
  1560. .el-form-item__content {
  1561. height: calc(100% - 18px);
  1562. .el-textarea {
  1563. height: 100%;
  1564. .el-textarea__inner {
  1565. height: 100%;
  1566. }
  1567. }
  1568. }
  1569. &.is-error {
  1570. .el-textarea__inner::placeholder {
  1571. color: #f56c6c;
  1572. }
  1573. }
  1574. }
  1575. }
  1576. }
  1577. .hcq-radius {
  1578. margin-top: 28px;
  1579. display: flex;
  1580. align-items: center;
  1581. color: #FFFFFF;
  1582. font-size: 14px;
  1583. :deep(.el-slider) {
  1584. padding-left: 4px;
  1585. height: 16px;
  1586. .el-slider__runway {
  1587. margin-right: 16px;
  1588. height: 2px;
  1589. .el-slider__bar {
  1590. height: 100%;
  1591. background-color: #2BFAFF;
  1592. }
  1593. .el-slider__button-wrapper {
  1594. top: -2px;
  1595. width: 6px;
  1596. height: 6px;
  1597. display: flex;
  1598. align-items: center;
  1599. justify-content: center;
  1600. .el-slider__button {
  1601. width: 100%;
  1602. height: 100%;
  1603. border: none;
  1604. background-color: #2BFAFF;
  1605. box-shadow: 0px 0px 4px 2px #2BFAFF;
  1606. }
  1607. }
  1608. }
  1609. .el-input-number {
  1610. width: 80px;
  1611. height: 100%;
  1612. display: flex;
  1613. .el-input-number__increase, .el-input-number__decrease {
  1614. width: 16px;
  1615. background-color: transparent;
  1616. border: none;
  1617. &:hover {
  1618. .el-icon {
  1619. color: #1CFEFF;
  1620. }
  1621. }
  1622. .el-icon {
  1623. color: rgba(255, 255, 255, 0.6);
  1624. font-size: 12px;
  1625. }
  1626. }
  1627. .el-input {
  1628. position: unset;
  1629. width: calc(100% - 16px * 2);
  1630. margin-left: 16px;
  1631. .el-input__wrapper {
  1632. padding: 0;
  1633. box-shadow: unset;
  1634. border: 1px solid rgba(255,255,255,0.6);
  1635. border-radius: 2px;
  1636. background-color: transparent;
  1637. word-break: break-all;
  1638. .el-input__inner {
  1639. height: 100%;
  1640. color: #FFFFFF;
  1641. font-size: 12px;
  1642. }
  1643. }
  1644. }
  1645. }
  1646. }
  1647. }
  1648. .draw-tips {
  1649. margin-top: 10px;
  1650. font-family: PingFang SC, PingFang SC;
  1651. font-weight: 400;
  1652. font-size: 14px;
  1653. color: #FFFFFF;
  1654. line-height: 20px;
  1655. }
  1656. .redraw {
  1657. margin-top: 16px;
  1658. display: flex;
  1659. gap: 10px;
  1660. >div {
  1661. display: flex;
  1662. align-items: center;
  1663. justify-content: center;
  1664. height: 28px;
  1665. background-color: #0062E9;
  1666. border-radius: 4px;
  1667. padding: 0 10px;
  1668. font-family: PingFang SC, PingFang SC;
  1669. font-weight: 400;
  1670. font-size: 12px;
  1671. color: #FFFFFF;
  1672. }
  1673. }
  1674. }
  1675. }
  1676. :deep(.cus-tab){
  1677. border-bottom: unset;
  1678. &.cus-tab-type1{
  1679. .cus-tab-item.active{
  1680. color: #1CFEFF;
  1681. &::after{
  1682. background-color: #1CFEFF;
  1683. }
  1684. }
  1685. }
  1686. }
  1687. }
  1688. .bottom-buttons {
  1689. width: 100%;
  1690. margin: 10px 0;
  1691. display: flex;
  1692. align-items: center;
  1693. justify-content: center;
  1694. >div {
  1695. margin-right: 8px;
  1696. &:last-child {
  1697. margin-right: 0;
  1698. }
  1699. }
  1700. .submit {
  1701. padding: 0 26px;
  1702. height: 32px;
  1703. background: linear-gradient(0deg, #1152C6, #4B8CFF);
  1704. border-radius: 4px;
  1705. display: flex;
  1706. align-items: center;
  1707. justify-content: center;
  1708. font-size: 14px;
  1709. font-family: PingFang SC-Regular, PingFang SC;
  1710. font-weight: 400;
  1711. color: #FFFFFF;
  1712. }
  1713. .cancel {
  1714. padding: 0 26px;
  1715. height: 32px;
  1716. background-color: transparent;
  1717. border: 1px solid #1a56d4;
  1718. border-radius: 4px;
  1719. display: flex;
  1720. align-items: center;
  1721. justify-content: center;
  1722. font-size: 14px;
  1723. font-family: PingFang SC-Regular, PingFang SC;
  1724. font-weight: 400;
  1725. color: #FFFFFF;
  1726. }
  1727. }
  1728. }
  1729. </style>