华西海圻ELN前端工程
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

653 lines
27 KiB

2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
2 weeks ago
  1. <template>
  2. <div>
  3. <LineLabel v-if="label" :label="label" />
  4. <div v-for="(item, index) in formConfig" :key="index">
  5. <template v-if="item.type === 'cardItem'">
  6. <div class="grid-container">
  7. <div v-for="(sItem, key) in item.config" class="form-item"
  8. :class="sItem.span == 1 ? 'full-row' : ''" :key="key">
  9. <template v-if="sItem.type === 'input'">
  10. <div class="form-title">{{ sItem.label }}</div>
  11. <HandleFormItem @blur="onBlur(key, $event)" :item="sItem" v-model="formFields[key]"
  12. @copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
  13. :orange-bg="orangeBgFields[key]" />
  14. </template>
  15. <template v-else-if="sItem.type === 'inputNumber'">
  16. <div class="form-title">{{ sItem.label }}</div>
  17. <HandleFormItem type="inputNumber" @blur="onBlur(key, $event)" :item="sItem"
  18. @input="onInputNumberChange(key, $event)" v-model="formFields[key]"
  19. @copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
  20. :orange-bg="orangeBgFields[key]" />
  21. </template>
  22. </div>
  23. </div>
  24. </template>
  25. <template v-else-if="item.type === 'conditionItem'">
  26. <div class="form-item ">
  27. <div class="form-title fs-16" v-if="item.label">{{ item.label }}</div>
  28. <div v-for="(sItem, key) in item.config" class="c-Item grid-container">
  29. <div class="p-r-20">
  30. <div class="form-title">{{ sItem.label }}</div>
  31. <div class="flex flex1">
  32. <HandleFormItem type="select" :item="sItem" v-model="formFields[key]"
  33. @copy="onCopy(sItem, key)" @change="onSelectChange(key, $event)"
  34. :error="errors[key]" @update:error="errors[key] = false"
  35. :orange-bg="orangeBgFields[key]" />
  36. </div>
  37. </div>
  38. <div class="p-l-20">
  39. <div v-show="isShowOther(formFields[key])">
  40. <div class="form-title">其他</div>
  41. <div class="flex flex1">
  42. <HandleFormItem @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
  43. v-model="formFields[sItem.otherCode]" @copy="onCopy(sItem, key)"
  44. :error="errors[sItem.otherCode]"
  45. @update:error="errors[sItem.otherCode] = false" />
  46. </div>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. </template>
  52. <template v-else-if="item.type === 'cellItem'">
  53. <div class="form-item ">
  54. <div class="form-title fs-16" v-if="item.label">{{ item.label }}</div>
  55. <div class="grid-container gap2">
  56. <div v-for="(sItem, key) in item.config" class="c-Item" :class="getSpanClass(sItem)" :key="key">
  57. <div class="form-title" v-if="sItem.label">{{ sItem.label }}</div>
  58. <div v-if="sItem.type === 'dateTime'" class="flex1">
  59. <HandleFormItem type="dateTime" :item="sItem" v-model="formFields[key]"
  60. @copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
  61. :orange-bg="orangeBgFields[key]" />
  62. </div>
  63. <div v-else-if="sItem.type === 'select'">
  64. <HandleFormItem type="select" :item="sItem" v-model="formFields[key]"
  65. @copy="onCopy(sItem, key)" @change="onSelectChange(key, $event)"
  66. :error="errors[key]" @update:error="errors[key] = false"
  67. :orange-bg="orangeBgFields[key]" />
  68. </div>
  69. <div v-else-if="sItem.type === 'input'">
  70. <HandleFormItem @blur="onBlur(key, $event)" :item="sItem" v-model="formFields[key]"
  71. @copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
  72. :orange-bg="orangeBgFields[key]" />
  73. </div>
  74. <div v-else-if="sItem.type === 'textarea'">
  75. <HandleFormItem @blur="onBlur(key, $event)" type="textarea" :item="sItem"
  76. v-model="formFields[key]" @copy="onCopy(sItem, key)" :error="errors[key]"
  77. @update:error="errors[key] = false" :orange-bg="orangeBgFields[key]" />
  78. </div>
  79. <div v-else-if="sItem.type === 'clickable'" class="flex1">
  80. <HandleFormItem type="clickable" @clickable="handleClickable(sItem, $event)"
  81. :item="sItem" :value="formFields[key]" />
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </template>
  87. <template v-else-if="item.type === 'step'">
  88. <div class="grid-container gap2">
  89. <div v-for="(sItem, key) in item.config" class="c-Item flex item-center"
  90. :class="getSpanClass(sItem)" :key="key">
  91. <div class="step-form-title" v-if="sItem.label">{{ sItem.label }}</div>
  92. <div v-if="sItem.type === 'dateTime'" class="flex1">
  93. <HandleFormItem type="dateTime" :item="sItem" v-model="formFields[key]"
  94. @copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
  95. :orange-bg="orangeBgFields[key]" />
  96. </div>
  97. <div v-else-if="sItem.type === 'select'" class="flex flex1">
  98. <HandleFormItem type="select" :item="sItem" style="width: auto;flex:1"
  99. v-model="formFields[key]" @copy="onCopy(sItem, key)"
  100. @change="onSelectChange(key, $event)" :error="errors[key]"
  101. @update:error="errors[key] = false" :orange-bg="orangeBgFields[key]" />
  102. <div v-show="isShowOther(formFields[key])" class="flex flex1">
  103. <div class="other-title">其他</div>
  104. <div class="flex">
  105. <HandleFormItem @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
  106. v-model="formFields[sItem.otherCode]" @copy="onCopy(sItem, key)"
  107. :error="errors[sItem.otherCode]" @update:error="errors[sItem.otherCode] = false"
  108. :orange-bg="orangeBgFields[sItem.otherCode]" />
  109. </div>
  110. </div>
  111. </div>
  112. <div v-else-if="sItem.type === 'input'" class="flex flex1">
  113. <HandleFormItem @blur="onBlur(key, $event)" class="flex1" :item="sItem"
  114. v-model="formFields[key]" @copy="onCopy(sItem, key)" :error="errors[key]"
  115. @update:error="errors[key] = false" :orange-bg="orangeBgFields[key]" />
  116. <HandleFormItem class="ml-10" v-if="sItem.subType === 'select'" type="select"
  117. :item="getSubItem(sItem)" v-model="formFields[sItem.subKey]" @copy="onCopy(sItem, key)"
  118. @change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]"
  119. @update:error="errors[sItem.subKey] = false"
  120. :orange-bg="orangeBgFields[sItem.subKey]" />
  121. <div class="ml-10" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
  122. <HandleFormItem class="ml-10" v-else-if="sItem.subType === 'clickable'" type="clickable"
  123. @clickable="handleClickable(sItem, $event)" :item="getClickableItem(sItem)"
  124. :value="formFields[sItem.subKey]" />
  125. <div v-show="isShowOther(formFields[sItem.subKey])" class="flex flex1">
  126. <div class="other-title">其他</div>
  127. <div class="flex">
  128. <HandleFormItem @blur="onBlur(key, $event)" :item="getOtherItem(sItem)"
  129. v-model="formFields[sItem.otherCode]" @copy="onCopy(sItem, key)"
  130. :error="errors[sItem.otherCode]" @update:error="errors[sItem.otherCode] = false"
  131. :orange-bg="orangeBgFields[sItem.otherCode]" />
  132. </div>
  133. </div>
  134. <!-- <div class="clickable" :class="getFillType(sItem.subFillType)" v-else-if = "sItem.subType ==='clickable'" @click="handleClickable(sItem,$event)">
  135. <span v-if="formFields[sItem.subKey]">{{ formFields[sItem.subKey] }}</span>
  136. <span v-else class="default-placeholder-text">请选择</span>
  137. </div> -->
  138. </div>
  139. <div v-else-if="sItem.type === 'inputNumber'" class="flex flex1">
  140. <HandleFormItem type="inputNumber" @blur="onBlur(key, $event)" class="flex1" :item="sItem"
  141. @input="onInputNumberChange(key, $event)" :value="formFields[key]"
  142. @copy="onCopy(sItem, key)" :error="errors[key]" @update:error="errors[key] = false"
  143. :orange-bg="orangeBgFields[key]" />
  144. <HandleFormItem class="ml-10" v-if="sItem.subType === 'select'" type="select"
  145. :item="getSubItem(sItem)" v-model="formFields[sItem.subKey]" @copy="onCopy(sItem, key)"
  146. @change="onSelectChange(sItem.subKey, $event)" :error="errors[sItem.subKey]"
  147. @update:error="errors[sItem.subKey] = false"
  148. :orange-bg="orangeBgFields[sItem.subKey]" />
  149. <div class="ml-10" v-else-if="sItem.subType === 'span'">{{ formFields[sItem.subKey] }}</div>
  150. <HandleFormItem class="ml-10" v-else-if="sItem.subType === 'clickable'"
  151. @clickable="handleClickable(sItem, $event)" type="clickable"
  152. :item="getClickableItem(sItem)" :value="formFields[sItem.subKey]" />
  153. <!-- <div class="clickable" :class="getFillType(sItem.subFillType)" v-else-if = "sItem.subType ==='clickable'" @click="handleClickable(sItem,$event)">
  154. <span v-if="formFields[sItem.subKey]">{{ formFields[sItem.subKey] }}</span>
  155. <span v-else class="default-placeholder-text">请选择</span>
  156. </div> -->
  157. </div>
  158. <div v-else-if="sItem.type === 'clickable'" class="flex flex1">
  159. <HandleFormItem type="clickable" @clickable="handleClickable(sItem, $event)"
  160. :error="errors[key]" :item="sItem" :value="formFields[key]" />
  161. </div>
  162. </div>
  163. </div>
  164. </template>
  165. </div>
  166. </div>
  167. </template>
  168. <script>
  169. import HandleFormItem from "./HandleFormItem.vue";
  170. import LineLabel from "./LineLabel.vue";
  171. export default {
  172. components: {
  173. HandleFormItem,
  174. LineLabel
  175. },
  176. props: {
  177. label: {//当前表单的标题
  178. type: String,
  179. default: "",
  180. },
  181. formConfig: {
  182. type: Array,
  183. value: () => [],
  184. },
  185. formData: {
  186. type: Object,
  187. value: () => ({})
  188. }
  189. },
  190. data() {
  191. return {
  192. formFields: {},//表单绑定字段
  193. allFieldsConfig: {},//包含config的所有字段,主要用于校验表单是否填写
  194. errors: {},//存储表单错误信息,用于标红提示
  195. orangeBgFields: {},// 存储需要橙色背景的字段
  196. };
  197. },
  198. watch: {
  199. formData: {
  200. immediate: true,
  201. deep: true, // 深度监听,以便检测嵌套对象变化
  202. handler(v) {
  203. if (v) {
  204. this.handleFormField(true);
  205. }
  206. }
  207. },
  208. formConfig: {
  209. immediate: true,
  210. deep: true, // 深度监听,以便检测嵌套对象变化
  211. handler(v) {
  212. this.handleFormField();
  213. }
  214. }
  215. },
  216. mounted() {
  217. this.handleFormField();
  218. },
  219. unmounted() {
  220. console.log("unmounted")
  221. this.formFields = {};//清空当前填写的数据
  222. },
  223. methods: {
  224. getFillType(type) {
  225. const typeObj = {
  226. actFill: "orange-border",//实际填写的边框颜色
  227. green: "green-border",
  228. preFill: "blue-border",//预填写的边框颜色
  229. }
  230. return typeObj[type] || ""
  231. },
  232. onInputNumberChange(key, val) {
  233. this.formFields[key] = val;
  234. // 清除该表单项的错误状态
  235. if (this.errors[key]) {
  236. this.$set(this.errors, key, false);
  237. }
  238. },
  239. //更新表单数据
  240. updateFormData(key, value) {
  241. this.formFields[key] = value;
  242. // 清除该表单项的错误状态
  243. if (this.errors[key]) {
  244. this.$set(this.errors, key, false);
  245. }
  246. },
  247. //批量更新表单数据
  248. batchUpdateFormData(data) {
  249. Object.keys(data).forEach(key => {
  250. this.formFields[key] = data[key];
  251. // 清除该表单项的错误状态
  252. if (this.errors[key]) {
  253. this.$set(this.errors, key, false);
  254. }
  255. })
  256. },
  257. handleClickable(sItem, event) {
  258. console.log("clickable", sItem)
  259. if (this.$store.state.template.templateStatus !== 'actFill') {
  260. return
  261. }
  262. this.$emit("clickable", sItem)
  263. },
  264. //根据span判断一行显示几列
  265. getSpanClass(sItem) {
  266. const spanArr = ["full-row", "", "three-row"]
  267. if (sItem.span) {
  268. return spanArr[sItem.span - 1]
  269. }
  270. return ""
  271. },
  272. //获取其他下拉框的配置
  273. getOtherItem(sItem) {
  274. return {
  275. label: "其他",
  276. fillType: sItem.fillType,
  277. maxlength: sItem.otherMaxlength || 50,
  278. }
  279. },
  280. getClickableItem(sItem) {
  281. return {
  282. label: "",
  283. type: "clickable",
  284. fillType: sItem.subFillType || sItem.fillType,
  285. }
  286. },
  287. getSubItem(sItem) {
  288. return {
  289. label: "",
  290. options: sItem.subOptions || [],
  291. fillType: sItem.subFillType || sItem.fillType,
  292. }
  293. },
  294. isShowOther(v = []) {
  295. // 确保v是数组类型,以避免类型错误
  296. const arr = Array.isArray(v) ? v : [v];
  297. //和凡哥商量,只要value为负数都显示其他
  298. return arr.some(item => item < 0);
  299. },
  300. // 根据formConfig回填form表单数据
  301. handleFormField(update = false) {
  302. const result = {};
  303. let config = {};
  304. const { formConfig, formData, formFields } = this;
  305. // 遍历配置
  306. formConfig.forEach((item) => {
  307. if (item.config) {
  308. // 合并配置项
  309. config = { ...config, ...item.config }
  310. // 处理每个配置项
  311. Object.keys(item.config).forEach(key => {
  312. const currentConfig = item.config[key];
  313. let value = formData[key];
  314. // 如果formFields中已经有值,保持原值(用户输入或之前设置的值)
  315. if (formFields[key] !== null &&
  316. formFields[key] !== undefined &&
  317. formFields[key] !== ''
  318. // typeof formFields[key] !== 'object'
  319. ) {
  320. // 保留原值,不使用formData中的值
  321. result[key] = formFields[key];
  322. } else {
  323. // 使用formData中的值
  324. result[key] = value;
  325. }
  326. // 处理特殊字段 - "其他"字段
  327. if (currentConfig.otherCode) {
  328. const { otherCode } = currentConfig;
  329. //如果是更新的话,优先使用formFields中的值
  330. if (update) {
  331. result[otherCode] = formFields[otherCode] || formData[otherCode] || '';
  332. } else {
  333. result[otherCode] = formData[otherCode] || formFields[otherCode] || '';
  334. }
  335. config[otherCode] = { label: "其他", parentKey: key, type: "input", fillType: currentConfig.fillType }
  336. }
  337. if (currentConfig.subKey) {
  338. const { subKey } = currentConfig;
  339. if (update) {
  340. result[subKey] = formFields[subKey] || formData[subKey] || '';
  341. } else {
  342. result[subKey] = formData[subKey] || formFields[subKey] || '';
  343. }
  344. config[subKey] = { label: currentConfig.label, subKey, type: currentConfig.subType, fillType: currentConfig.subFillType || currentConfig.fillType }
  345. }
  346. });
  347. // 处理可能存在的直接otherCode字段
  348. if (item.config?.otherCode) {
  349. config[item.config?.otherCode] = item.config?.otherCode;
  350. }
  351. }
  352. });
  353. // 更新表单字段
  354. this.formFields = result;
  355. this.allFieldsConfig = config;
  356. },
  357. //判断是否禁用
  358. getDisabled() {
  359. const { item } = this;
  360. const { fillType } = item;
  361. if (item.hasOwnProperty("disabled")) {
  362. return item.disabled
  363. } else {
  364. const { templateStatus } = this.$store.state.template;
  365. if (fillType === "actFill") {//当模板状态是实际填写时,只有当fillType是actFill时才能填写
  366. return templateStatus !== "actFill"
  367. } else if (fillType === "preFill") {//当模板状态是预填写时,只有当fillType是preFill才能填写
  368. return templateStatus !== "preFill"
  369. } else {
  370. return true
  371. }
  372. }
  373. },
  374. // 表单数据校验
  375. validateFormData() {
  376. const { formFields, allFieldsConfig } = this;
  377. const { templateStatus } = this.$store.state.template;
  378. const errors = [];
  379. // 清空之前的错误状态
  380. this.errors = {};
  381. for (const key in allFieldsConfig) {
  382. const o = allFieldsConfig[key];
  383. if (o.otherCode) {//
  384. if (o.type === "select") {
  385. const isSelectedOther = this.isShowOther(formFields[key]);
  386. if (!isSelectedOther) {//如果其他选项没有被选择,清空其他字段
  387. formFields[o.otherCode] = "";
  388. }
  389. } else if (o.subType === "select") {
  390. const isSelectedOther = this.isShowOther(formFields[o.subKey]);
  391. if (!isSelectedOther) {//如果其他选项没有被选择,清空其他字段
  392. formFields[o.otherCode] = "";
  393. }
  394. }
  395. }
  396. if (this.isValueEmpty(formFields[key])) {
  397. // 其他字段需要判断是否显示再校验
  398. if (o.label === "其他" && !this.isShowOther(formFields[o.parentKey])) {
  399. continue
  400. }
  401. //span的字段不校验
  402. if (o.type === "span") {
  403. continue
  404. }
  405. if (o.fillType == templateStatus && !o.disabled) {
  406. let prefix = "";
  407. if (o.type === "input" || o.type === "inputNumber" || o.type === "textarea") {
  408. prefix = "填写";
  409. } else {
  410. prefix = "选择";
  411. }
  412. const errorItem = {
  413. field: key,
  414. label: o.label,
  415. error: `${prefix}${o.label}`
  416. };
  417. errors.push(errorItem);
  418. this.$set(this.errors, key, true);
  419. }
  420. }
  421. }
  422. return {
  423. valid: errors.length === 0,
  424. errors: errors
  425. };
  426. },
  427. // 判断值是否为空
  428. isValueEmpty(value) {
  429. if (value === null || value === undefined || value === '') {
  430. return true;
  431. }
  432. if (typeof value === 'string' && value.trim() === '') {
  433. return true;
  434. }
  435. if (Array.isArray(value) && value.length === 0) {
  436. return true;
  437. }
  438. return false;
  439. },
  440. getFormData() {
  441. // 数据校验
  442. const validateResult = this.validateFormData();
  443. return new Promise((resolve, reject) => {
  444. if (validateResult.valid) {
  445. resolve(this.formFields);
  446. } else {
  447. // this.$message.error("表单内容未填完,请填写后再提交");
  448. reject(validateResult.errors[0].error);
  449. }
  450. });
  451. },
  452. //直接获取表单数据,不做校验
  453. getFilledFormData() {
  454. return this.formFields;
  455. },
  456. getFormDataByKey(key) {
  457. return this.formFields[key];
  458. },
  459. onBlur(key, val) {
  460. // compareTo 功能:当fillType==="actFill"时,判断当前值是否与compareTo字段的值一样,如果不一样则将当前input框的背景色标记成橙色
  461. const currentFieldConfig = this.allFieldsConfig[key];
  462. if (currentFieldConfig && currentFieldConfig.fillType === "actFill" && currentFieldConfig.compareTo) {
  463. const compareToKey = currentFieldConfig.compareTo;
  464. const compareToValue = this.formFields[compareToKey];
  465. // 比较当前值和compareTo值,如果不相等则设置橙色背景
  466. if (val !== compareToValue) {
  467. this.$set(this.orangeBgFields, key, true);
  468. } else {
  469. // 相等则移除橙色背景
  470. this.$set(this.orangeBgFields, key, false);
  471. }
  472. }
  473. this.$emit("blur", { key, value: val, ...this.formFields });
  474. },
  475. onSelectChange(key, val) {
  476. // 获取对应的配置
  477. const currentConfig = this.allFieldsConfig[key];
  478. // // 确保多选下拉框的值是数组类型
  479. // if (currentConfig && currentConfig.multiple) {
  480. // // 多选情况,确保值为数组类型
  481. // this.formFields[key] = Array.isArray(val) ? val : (val ? [val] : []);
  482. // } else {
  483. // 单选情况
  484. this.formFields[key] = val;
  485. // }
  486. this.$emit("select", { key, value: val });
  487. // 清除该表单项的错误状态
  488. if (this.errors[key]) {
  489. this.$set(this.errors, key, false);
  490. }
  491. },
  492. //复制
  493. onCopy(config, key) {
  494. const { formFields } = this;
  495. if (config.copyFrom) {
  496. formFields[key] = formFields[config.copyFrom];
  497. this.onBlur(key, formFields[key]);
  498. }
  499. },
  500. },
  501. }
  502. </script>
  503. <style lang="scss">
  504. .grid-container {
  505. display: grid;
  506. grid-template-columns: repeat(2, 1fr);
  507. /* 默认2列 */
  508. gap: 0 20px;
  509. }
  510. .gap2 {
  511. gap: 0 64px;
  512. }
  513. .w-100 {
  514. width: 100%;
  515. }
  516. .form-item {
  517. background: #fff;
  518. padding: 20px;
  519. border-radius: 8px;
  520. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
  521. margin-top: 20px;
  522. padding: 20px;
  523. border-radius: 5px 5px;
  524. }
  525. /* 或者使用 span 语法 */
  526. .full-row {
  527. grid-column: span 2;
  528. }
  529. .three-row {
  530. grid-column: span 3;
  531. }
  532. .c-Item {
  533. &:not(:last-child) {
  534. margin-bottom: 16px;
  535. }
  536. }
  537. .eo {
  538. &:nth-child(even) {
  539. padding-left: 20px;
  540. }
  541. &:nth-child(odd) {
  542. padding-right: 20px;
  543. }
  544. }
  545. .default-placeholder-text {
  546. color: #C0C4CC;
  547. }
  548. .form-title {
  549. margin-bottom: 12px;
  550. font-size: 14px;
  551. font-weight: normal;
  552. color: #606266;
  553. }
  554. .step-form-title {
  555. font-size: 14px;
  556. font-weight: normal;
  557. color: #606266;
  558. width: 150px;
  559. text-align: right;
  560. padding-right: 10px;
  561. }
  562. .p-r-20 {
  563. padding-right: 20px;
  564. }
  565. .p-l-20 {
  566. padding-left: 20px;
  567. }
  568. .fs-16 {
  569. font-size: 0.96rem;
  570. font-weight: bold;
  571. color: #464647
  572. }
  573. .flex1 {
  574. flex: 1;
  575. }
  576. .flex {
  577. display: flex;
  578. }
  579. .other-title {
  580. width: 50px;
  581. text-align: right;
  582. margin: 0 10px;
  583. font-size: 14px;
  584. font-weight: normal;
  585. color: #606266;
  586. }
  587. .mr-24 {
  588. margin-right: 24px;
  589. }
  590. .sub-select {
  591. width: 100px;
  592. margin-left: 10px;
  593. }
  594. .orange-border {
  595. border-color: #f9c588;
  596. }
  597. .green-border {
  598. border-color: green;
  599. }
  600. .blue-border {
  601. border-color: #4ea2ff;
  602. }
  603. .ml-10 {
  604. margin-left: 10px;
  605. }
  606. </style>