edit.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. <template>
  2. <el-dialog
  3. class="api-edit"
  4. v-model="showDialog"
  5. :title="`${formData.sourceId ? t('message.dateCenter.actions.edit') : t('message.dateCenter.actions.createSource')}`"
  6. width="800px"
  7. :close-on-click-modal="false"
  8. :close-on-press-escape="false"
  9. >
  10. <el-form class="inline-form" ref="formRef" :model="formData" :rules="ruleForm" label-width="140px">
  11. <el-form-item :label="t('message.dateCenter.labels.sourceKey')" prop="key">
  12. <el-input v-model="formData.key" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.sourceKey')}`" :disabled="formData.sourceId" />
  13. </el-form-item>
  14. <el-form-item :label="t('message.dateCenter.labels.sourceName')" prop="name">
  15. <el-input v-model="formData.name" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.sourceName')}`" />
  16. </el-form-item>
  17. <el-form-item :label="t('message.dateCenter.labels.sourceDesc')" prop="desc">
  18. <el-input v-model="formData.desc" type="textarea" :placeholder="t('message.dateCenter.placeholders.input')"></el-input>
  19. </el-form-item>
  20. <el-form-item :label="t('message.dateCenter.labels.sourceFrom')" prop="from" v-if="!formData.sourceId">
  21. <el-radio-group v-model="formData.from">
  22. <el-radio :label="1">{{ t('message.dateCenter.options.api') }}</el-radio>
  23. <el-radio :label="4">{{ t('message.dateCenter.options.device') }}</el-radio>
  24. <el-radio :label="2">{{ t('message.dateCenter.options.db') }}</el-radio>
  25. </el-radio-group>
  26. </el-form-item>
  27. <el-divider content-position="left">{{ t('message.dateCenter.tabs.sourceConfig') }}</el-divider>
  28. <div v-if="formData.from == 1">
  29. <el-form-item :label="t('message.dateCenter.labels.method')" prop="config.method">
  30. <el-select v-model="formData.config.method" :rules="ruleForm['config.method']" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.method')}`">
  31. <el-option v-for="item in methodData" :key="item.value" :label="item.label" :value="item.value" />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item :label="t('message.dateCenter.labels.url')" prop="config.url">
  35. <el-input v-model="formData.config.url" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.url')}`" :rules="ruleForm['config.url']" />
  36. </el-form-item>
  37. <el-form-item :label="t('message.dateCenter.labels.interval')" prop="config.cronExpression">
  38. <div style="display: flex">
  39. <el-input v-model="formData.config.cronExpression" :placeholder="`${t('message.dateCenter.placeholders.input')} cron`" :rules="ruleForm['config.cronExpression']" />
  40. <el-button type="success" @click="showCron('config')" style="margin-left: 5px">{{ t('message.dateCenter.actions.edit') }}</el-button>
  41. </div>
  42. </el-form-item>
  43. <div class="box-content">
  44. <div>
  45. <div
  46. v-for="(item, index) in requestParams"
  47. :key="index"
  48. style="padding: 10px; border: 1px solid #eee; margin-bottom: 10px; position: relative"
  49. >
  50. <div class="conicon" style="width: 100%; text-align: right; position: absolute; right: -8px; top: -8px; color: red">
  51. <el-icon @click="delParams(index)">
  52. <CircleClose />
  53. </el-icon>
  54. </div>
  55. <div style="display: flex">
  56. <el-divider content-position="left">{{ t('message.dateCenter.tabs.reqParams') }}</el-divider>
  57. </div>
  58. <div class="content-f" v-for="(aaa, bbb) in item" :key="bbb">
  59. <el-select v-model="aaa.type" :placeholder="t('message.dateCenter.labels.paramType')" style="width: 320px">
  60. <el-option v-for="item in paramData" :key="item.value" :label="item.label" :value="item.value" />
  61. </el-select>
  62. <el-input v-model="aaa.name" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.paramTitle')}`" style="width: 320px" />
  63. <el-input v-model="aaa.key" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.paramKey')}`" style="width: 320px" />
  64. <el-input v-model="aaa.value" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.paramValue')}`" style="width: 320px" />
  65. <div class="conicon">
  66. <el-icon @click="delParamss(index, bbb)">
  67. <Delete />
  68. </el-icon>
  69. </div>
  70. </div>
  71. <el-button type="primary" class="addbutton" @click="addParams(index)">{{ t('message.dateCenter.actions.add') }}</el-button>
  72. <div style=""></div>
  73. </div>
  74. </div>
  75. </div>
  76. <el-button type="success" class="addbutton" @click="addParamss">{{ t('message.dateCenter.actions.add') }}</el-button>
  77. </div>
  78. <div v-if="formData.from == 4">
  79. <el-form-item :label="t('message.dateCenter.labels.sourceFrom')">
  80. <el-radio-group v-model="deviceOrProduct" @change=";(formData.devconfig.productKey = ''), (formData.devconfig.deviceKey = '')">
  81. <el-radio label="device">{{ t('message.dateCenter.options.device') }}</el-radio>
  82. <el-radio label="product">{{ t('message.dateCenter.labels.productKey') }}</el-radio>
  83. </el-radio-group>
  84. </el-form-item>
  85. <el-form-item :label="t('message.dateCenter.labels.deviceKey')" v-if="deviceOrProduct == 'device'" prop="devconfig.deviceKey">
  86. <el-select
  87. v-model="formData.devconfig.deviceKey"
  88. :rules="ruleForm['devconfig.deviceKey']"
  89. filterable
  90. :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.deviceKey')}`"
  91. @change="formData.devconfig.productKey = ''"
  92. style="width: 100%"
  93. >
  94. <el-option v-for="item in sourceData" :key="item.key" :label="item.name" :value="item.key">
  95. <span style="float: left">{{ item.name }}</span>
  96. <span style="float: right; font-size: 13px">{{ item.key }}</span>
  97. </el-option>
  98. </el-select>
  99. </el-form-item>
  100. <el-form-item :label="t('message.dateCenter.labels.productKey')" v-if="deviceOrProduct == 'product'" prop="devconfig.productKey">
  101. <el-select
  102. v-model="formData.devconfig.productKey"
  103. :rules="ruleForm['devconfig.productKey']"
  104. filterable
  105. :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.productKey')}`"
  106. @change="formData.devconfig.deviceKey = ''"
  107. style="width: 100%"
  108. >
  109. <el-option v-for="item in producList" :key="item.key" :label="item.name" :value="item.key">
  110. <span style="float: left">{{ item.name }}</span>
  111. <span style="float: right; font-size: 13px">{{ item.key }}</span>
  112. </el-option>
  113. </el-select>
  114. </el-form-item>
  115. </div>
  116. <div v-if="formData.from == 2">
  117. <el-form-item :label="t('message.dateCenter.labels.dbType')" prop="tabconfig.type">
  118. <el-radio-group v-model="formData.tabconfig.type" :rules="ruleForm['tabconfig.type']">
  119. <el-radio label="mysql">mysql</el-radio>
  120. <el-radio label="mssql">mssql</el-radio>
  121. </el-radio-group>
  122. </el-form-item>
  123. <div class="inline">
  124. <el-form-item :label="t('message.dateCenter.labels.host')" prop="tabconfig.host">
  125. <el-input v-model="formData.tabconfig.host" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.host')}`" :rules="ruleForm['tabconfig.host']" />
  126. </el-form-item>
  127. <el-form-item :label="t('message.dateCenter.labels.port')" prop="tabconfig.port">
  128. <el-input v-model="formData.tabconfig.port" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.port')}`" :rules="ruleForm['tabconfig.port']" />
  129. </el-form-item>
  130. </div>
  131. <div class="inline">
  132. <el-form-item :label="t('message.dateCenter.labels.user')" prop="tabconfig.user">
  133. <el-input v-model="formData.tabconfig.user" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.user')}`" :rules="ruleForm['tabconfig.user']" />
  134. </el-form-item>
  135. <el-form-item :label="t('message.dateCenter.labels.password')" prop="tabconfig.passwd">
  136. <el-input v-model="formData.tabconfig.passwd" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.password')}`" :rules="ruleForm['tabconfig.passwd']" />
  137. </el-form-item>
  138. </div>
  139. <el-form-item :label="t('message.dateCenter.labels.dbName')" prop="tabconfig.dbName">
  140. <el-input v-model="formData.tabconfig.dbName" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.dbName')}`" :rules="ruleForm['tabconfig.dbName']" />
  141. </el-form-item>
  142. <el-form-item :label="t('message.dateCenter.labels.expression')" prop="tabconfig.queryType">
  143. <el-radio-group v-model="formData.tabconfig.queryType" :rules="ruleForm['tabconfig.queryType']">
  144. <el-radio label="tableName">{{ t('message.dateCenter.columns.value') }}</el-radio>
  145. <el-radio label="sql">Sql</el-radio>
  146. </el-radio-group>
  147. </el-form-item>
  148. <el-form-item label="" prop="tabconfig.tableName">
  149. <el-input
  150. v-model="formData.tabconfig.tableName"
  151. type="textarea"
  152. :placeholder="formData.tabconfig.queryType == 'sql' ? `${t('message.dateCenter.placeholders.input')} sql` : `${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.tableName')}`"
  153. />
  154. </el-form-item>
  155. <el-form-item :label="t('message.dateCenter.labels.pk')" prop="tabconfig.pk">
  156. <el-input v-model="formData.tabconfig.pk" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.pk')}`" :rules="ruleForm['tabconfig.pk']" />
  157. </el-form-item>
  158. <el-form-item :label="t('message.dateCenter.labels.num')" prop="tabconfig.num">
  159. <el-input v-model="formData.tabconfig.num" :placeholder="`${t('message.dateCenter.placeholders.input')} ${t('message.dateCenter.labels.num')}`" :rules="ruleForm['tabconfig.num']" />
  160. </el-form-item>
  161. <el-form-item :label="t('message.dateCenter.labels.cronExpression')" prop="tabconfig.cronExpression">
  162. <div style="display: flex">
  163. <el-input v-model="formData.tabconfig.cronExpression" :placeholder="`${t('message.dateCenter.placeholders.input')} cron`" :rules="ruleForm['tabconfig.cronExpression']" />
  164. <el-button type="success" @click="showCron('tabconfig')" style="margin-left: 5px">{{ t('message.dateCenter.actions.edit') }}</el-button>
  165. </div>
  166. </el-form-item>
  167. </div>
  168. </el-form>
  169. <template #footer>
  170. <div class="dialog-footer">
  171. <el-button @click="onTest" type="warning" v-if="sourceId > 0">{{ t('message.dateCenter.actions.search') }}</el-button>
  172. <el-button @click="showDialog = false">{{ t('message.dateCenter.messages.cancel') }}</el-button>
  173. <el-button type="primary" @click="onSubmit">{{ t('message.dateCenter.messages.confirm') }}</el-button>
  174. </div>
  175. </template>
  176. </el-dialog>
  177. <el-dialog v-model="dialogVisible" :title="'Json'" width="30%">
  178. <JsonViewer :value="jsonData" boxed sort theme="jv-dark" @click="onKeyclick" />
  179. <template #footer>
  180. <span class="dialog-footer">
  181. <el-button @click="dialogVisible = false">{{ t('message.dateCenter.messages.cancel') }}</el-button>
  182. </span>
  183. </template>
  184. </el-dialog>
  185. <el-dialog v-model="cronShow" :title="'Cron'" width="60%">
  186. <vue3cron @handlelisten="handlelisten" :type="crontype" @close="cronclose"></vue3cron>
  187. </el-dialog>
  188. </template>
  189. <script lang="ts" setup>
  190. import { ref, reactive, nextTick, computed } from 'vue'
  191. import { useI18n } from 'vue-i18n'
  192. import api from '/@/api/datahub'
  193. import deviceApi from '/@/api/device'
  194. import { ruleRequired } from '/@/utils/validator'
  195. import 'vue3-json-viewer/dist/index.css'
  196. import vue3cron from '/@/components/vue3cron/vue3cron.vue'
  197. import { ElMessage } from 'element-plus'
  198. import { Delete, CircleClose } from '@element-plus/icons-vue'
  199. const emit = defineEmits(['typeList'])
  200. const showDialog = ref(false)
  201. const { t } = useI18n()
  202. const deviceOrProduct = ref('device')
  203. const dialogVisible = ref(false)
  204. const cronShow = ref(false)
  205. const formRef = ref()
  206. const jsonData = ref()
  207. const crontype = ref()
  208. const sourceData = ref<Array<{ key: string; name: string }>>([])
  209. const producList = ref<Array<{ key: string; name: string }>>([])
  210. const sourceId = ref()
  211. const methodData = ref([
  212. {
  213. label: 'GET',
  214. value: 'get',
  215. },
  216. {
  217. label: 'POST',
  218. value: 'post',
  219. },
  220. ])
  221. const paramData = ref([
  222. {
  223. label: 'header',
  224. value: 'header',
  225. },
  226. {
  227. label: 'body',
  228. value: 'body',
  229. },
  230. {
  231. label: 'param',
  232. value: 'param',
  233. },
  234. ])
  235. const requestParams = ref([
  236. [
  237. {
  238. type: '',
  239. key: '',
  240. name: '',
  241. value: '',
  242. },
  243. ],
  244. ])
  245. const delParams = (index: number) => {
  246. requestParams.value.splice(index, 1)
  247. }
  248. const delParamss = (index: number, bbb: number) => {
  249. requestParams.value[index].splice(bbb, 1)
  250. }
  251. const addParamss = () => {
  252. requestParams.value.push([
  253. {
  254. type: '',
  255. key: '',
  256. name: '',
  257. value: '',
  258. },
  259. ])
  260. }
  261. const addParams = (index: number) => {
  262. requestParams.value[index].push({
  263. type: '',
  264. key: '',
  265. name: '',
  266. value: '',
  267. })
  268. }
  269. const handlelisten = (e: any) => {
  270. if (e.type == 'config') {
  271. formData.config.cronExpression = e.cron
  272. } else if (e.type == 'tabconfig') {
  273. formData.tabconfig.cronExpression = e.cron
  274. }
  275. }
  276. const showCron = (type: string) => {
  277. crontype.value = type
  278. cronShow.value = true
  279. }
  280. const cronclose = () => {
  281. cronShow.value = false
  282. }
  283. const onTest = () => {
  284. if (formData.from == 1) {
  285. api.common.api(sourceId.value).then((res: any) => {
  286. jsonData.value = JSON.parse(res.data)
  287. dialogVisible.value = true
  288. })
  289. } else if (formData.from == 4) {
  290. api.common.devapi(sourceId.value).then((res: any) => {
  291. jsonData.value = JSON.parse(res.data)
  292. dialogVisible.value = true
  293. })
  294. }
  295. }
  296. const baseForm = {
  297. sourceId: undefined,
  298. name: '',
  299. key: '',
  300. desc: '',
  301. from: 1,
  302. config: {
  303. method: '',
  304. url: '',
  305. cronExpression: '',
  306. requestParams: [],
  307. },
  308. devconfig: {
  309. deviceKey: '',
  310. productKey: '',
  311. },
  312. tabconfig: {
  313. type: 'mysql',
  314. host: '',
  315. port: '',
  316. user: '',
  317. passwd: '',
  318. dbName: '',
  319. queryType: '',
  320. tableName: '',
  321. pk: '',
  322. num: '',
  323. cronExpression: '',
  324. },
  325. }
  326. const onKeyclick = () => {}
  327. const formData = reactive({
  328. ...baseForm,
  329. })
  330. const ruleForm = computed(() => {
  331. return {
  332. key: [ruleRequired(`${t('message.dateCenter.labels.sourceKey')}${t('message.dateCenter.placeholders.input')}`)],
  333. name: [ruleRequired(`${t('message.dateCenter.labels.sourceName')}${t('message.dateCenter.placeholders.input')}`)],
  334. from: [ruleRequired(`${t('message.dateCenter.labels.sourceFrom')}${t('message.dateCenter.placeholders.input')}`)],
  335. 'config.method': [
  336. { required: true, message: `${t('message.dateCenter.labels.method')}${t('message.dateCenter.placeholders.input')}` , trigger: 'change' },
  337. {
  338. validator: (rule: any, value: string, callback: any) => {
  339. if (formData.from === 1 && !formData.config.method) {
  340. callback(new Error(`${t('message.dateCenter.labels.method')}${t('message.dateCenter.placeholders.input')}`))
  341. } else {
  342. callback()
  343. }
  344. },
  345. trigger: 'change',
  346. },
  347. ],
  348. 'config.url': [ruleRequired(`${t('message.dateCenter.labels.url')}${t('message.dateCenter.placeholders.input')}`)],
  349. 'config.cronExpression': [ruleRequired(`${t('message.dateCenter.labels.interval')}${t('message.dateCenter.placeholders.input')}`)],
  350. 'devconfig.deviceKey': [ruleRequired(`${t('message.dateCenter.labels.deviceKey')}${t('message.dateCenter.placeholders.input')}`)],
  351. 'devconfig.productKey': [ruleRequired(`${t('message.dateCenter.labels.productKey')}${t('message.dateCenter.placeholders.input')}`)],
  352. 'tabconfig.type': [ruleRequired(`${t('message.dateCenter.labels.dbType')}${t('message.dateCenter.placeholders.input')}`)],
  353. 'tabconfig.host': [ruleRequired(`${t('message.dateCenter.labels.host')}${t('message.dateCenter.placeholders.input')}`)],
  354. 'tabconfig.port': [ruleRequired(`${t('message.dateCenter.labels.port')}${t('message.dateCenter.placeholders.input')}`)],
  355. 'tabconfig.user': [ruleRequired(`${t('message.dateCenter.labels.user')}${t('message.dateCenter.placeholders.input')}`)],
  356. 'tabconfig.passwd': [ruleRequired(`${t('message.dateCenter.labels.password')}${t('message.dateCenter.placeholders.input')}`)],
  357. 'tabconfig.dbName': [ruleRequired(`${t('message.dateCenter.labels.dbName')}${t('message.dateCenter.placeholders.input')}`)],
  358. 'tabconfig.queryType': [ruleRequired(`${t('message.dateCenter.labels.expression')}${t('message.dateCenter.placeholders.input')}`)],
  359. 'tabconfig.tableName': [ruleRequired(`${t('message.dateCenter.placeholders.input')}`)],
  360. 'tabconfig.pk': [ruleRequired(`${t('message.dateCenter.labels.pk')}${t('message.dateCenter.placeholders.input')}`)],
  361. 'tabconfig.num': [ruleRequired(`${t('message.dateCenter.labels.num')}${t('message.dateCenter.placeholders.input')}`)],
  362. 'tabconfig.cronExpression': [ruleRequired(`${t('message.dateCenter.labels.cronExpression')}${t('message.dateCenter.placeholders.input')}`)],
  363. }
  364. })
  365. const getDevData = () => {
  366. api.common.getdevList({}).then((res: any) => {
  367. sourceData.value = res.device
  368. })
  369. deviceApi.product.getLists().then((res: any) => {
  370. producList.value = res.product
  371. })
  372. }
  373. const onSubmit = async () => {
  374. await formRef.value.validate()
  375. if (formData.from == 1) {
  376. let form = {
  377. sourceId: sourceId.value ? sourceId.value : '',
  378. key: formData.key,
  379. name: formData.name,
  380. desc: formData.desc,
  381. from: formData.from,
  382. config: {
  383. ...formData.config,
  384. requestParams: requestParams.value,
  385. },
  386. }
  387. const theApi = sourceId.value ? api.common.edit : api.common.add
  388. await theApi(form)
  389. ElMessage.success(t('message.dateCenter.messages.opSuccess'))
  390. resetForm()
  391. showDialog.value = false
  392. emit('typeList')
  393. } else if (formData.from == 4) {
  394. let form = {
  395. sourceId: formData.sourceId ? formData.sourceId : '',
  396. key: formData.key,
  397. name: formData.name,
  398. desc: formData.desc,
  399. from: formData.from,
  400. config: formData.devconfig,
  401. }
  402. const theApi = formData.sourceId ? api.common.devedit : api.common.devadd
  403. await theApi(form)
  404. ElMessage.success('操作成功')
  405. resetForm()
  406. showDialog.value = false
  407. emit('typeList')
  408. } else if (formData.from == 2) {
  409. let form = {
  410. sourceId: formData.sourceId ? formData.sourceId : '',
  411. key: formData.key,
  412. name: formData.name,
  413. desc: formData.desc,
  414. from: formData.from,
  415. config: formData.tabconfig,
  416. }
  417. const theApi = formData.sourceId ? api.common.dbedit : api.common.dbadd
  418. await theApi(form)
  419. ElMessage.success('操作成功')
  420. resetForm()
  421. showDialog.value = false
  422. emit('typeList')
  423. }
  424. }
  425. const resetForm = async () => {
  426. Object.assign(formData, { ...baseForm })
  427. formRef.value && formRef.value.resetFields()
  428. requestParams.value = [
  429. [
  430. {
  431. type: '',
  432. key: '',
  433. name: '',
  434. value: '',
  435. },
  436. ],
  437. ]
  438. }
  439. const openDialog = async (row: any) => {
  440. resetForm()
  441. showDialog.value = true
  442. nextTick(() => {
  443. if (row) {
  444. sourceId.value = row.sourceId
  445. api.common.detail(row.sourceId).then((res: any) => {
  446. Object.assign(formData, { ...res.data })
  447. if (res.data.from == 1) {
  448. formData.config = res.data.apiConfig
  449. requestParams.value = res.data.apiConfig.requestParams
  450. } else if (res.data.from == 4) {
  451. deviceOrProduct.value = res.data.deviceConfig.deviceKey ? 'device' : 'product'
  452. formData.devconfig = res.data.deviceConfig
  453. } else if (res.data.from == 2) {
  454. formData.tabconfig = res.data.dbConfig
  455. }
  456. })
  457. }
  458. getDevData()
  459. })
  460. }
  461. defineExpose({ openDialog })
  462. </script>
  463. <style scoped lang="scss">
  464. .inline {
  465. display: inline-flex;
  466. }
  467. .el-input__wrapper {
  468. width: 98%;
  469. }
  470. .box-content {
  471. border: 1px solid #e8e8e8;
  472. margin: 10px;
  473. padding: 10px;
  474. }
  475. .content-f {
  476. display: flex;
  477. margin-bottom: 10px;
  478. }
  479. .content-f .el-input__wrapper {
  480. margin-right: 5px;
  481. }
  482. .addbutton {
  483. width: 100%;
  484. margin-top: 10px;
  485. background: #fff;
  486. border: 1px solid #d1d1d1;
  487. color: #8d8b8b;
  488. }
  489. .conicon {
  490. width: 55px;
  491. height: 25px;
  492. font-size: 28px;
  493. line-height: 28px;
  494. cursor: pointer;
  495. }
  496. .jv-node {
  497. margin-left: 25px;
  498. }
  499. </style>