StyleFormPanel.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. <template>
  2. <div class="style-wrap">
  3. <el-button
  4. type="primary"
  5. class="inline-large-button mb10"
  6. icon="el-icon-plus"
  7. size="mini"
  8. @click="addDataDialog"
  9. >
  10. 添加样式
  11. </el-button>
  12. <!-- 样式表格 -->
  13. <el-table :data="styleTableData" style="width: 100%">
  14. <el-table-column label="序号" type="index" width="50"> </el-table-column>
  15. <el-table-column prop="styleName" label="样式名" width="100">
  16. </el-table-column>
  17. <el-table-column prop="styleDescription" label="描述" width="100">
  18. </el-table-column>
  19. <el-table-column label="操作">
  20. <template slot-scope="scope">
  21. <el-dropdown>
  22. <el-button type="warning" plain size="small">
  23. 处理<i class="el-icon-arrow-down el-icon--right"></i>
  24. </el-button>
  25. <el-dropdown-menu slot="dropdown">
  26. <el-dropdown-item>
  27. <el-button
  28. size="mini"
  29. type="text"
  30. icon="el-icon-edit"
  31. @click="editHandler(scope.row, scope.$index)"
  32. >修改
  33. </el-button>
  34. </el-dropdown-item>
  35. <el-dropdown-item>
  36. <el-button
  37. size="mini"
  38. type="text"
  39. icon="el-icon-delete"
  40. @click="delHandler(scope.$index)"
  41. >删除
  42. </el-button>
  43. </el-dropdown-item>
  44. </el-dropdown-menu>
  45. </el-dropdown>
  46. </template>
  47. </el-table-column>
  48. </el-table>
  49. <el-dialog title="编辑样式" :visible.sync="dialogShow" width="50%">
  50. <el-form
  51. ref="styleFormDataRef"
  52. :model="styleFormData"
  53. label-width="100px"
  54. :rules="styleFormRules"
  55. >
  56. <el-form-item label="样式名" prop="styleName">
  57. <el-input v-model="styleFormData.styleName"></el-input>
  58. </el-form-item>
  59. <el-form-item label="样式描述" prop="styleDescription">
  60. <el-input
  61. type="textarea"
  62. v-model="styleFormData.styleDescription"
  63. ></el-input>
  64. </el-form-item>
  65. <el-form-item label="样式类型" prop="styleType">
  66. <el-radio-group v-model="styleFormData.styleType" size="small">
  67. <el-radio-button :label="0">行样式</el-radio-button>
  68. <el-radio-button :label="1">字段样式</el-radio-button>
  69. <el-radio-button :label="2">字典样式</el-radio-button>
  70. </el-radio-group>
  71. </el-form-item>
  72. <div v-show="styleFormData.styleType == 0">
  73. <el-form-item label="背景颜色" prop="rowBgColor">
  74. <input
  75. type="color"
  76. :value="styleFormData.rowBgColor"
  77. @input="selectColors($event, 'rowBgColor')"
  78. />
  79. </el-form-item>
  80. </div>
  81. <div v-show="styleFormData.styleType == 1">
  82. <el-form-item label="样式生效字段" prop="styleTable">
  83. <el-col :span="10">
  84. <el-select
  85. v-model="styleFormData.styleTable"
  86. value-key=""
  87. placeholder="请选择表"
  88. filterable
  89. >
  90. <el-option
  91. v-for="item in tableList"
  92. :key="item.tableName"
  93. :label="item.tableComment"
  94. :value="item.tableName"
  95. >
  96. <span style="float: left">{{ item.tableComment }}</span>
  97. <span style="float: right; color: #8492a6; font-size: 13px">{{
  98. item.tableName
  99. }}</span>
  100. </el-option>
  101. </el-select>
  102. </el-col>
  103. <el-col :span="10">
  104. <el-select
  105. v-model="styleFormData.styleField"
  106. value-key=""
  107. placeholder="请选择字段"
  108. filterable
  109. >
  110. <el-option
  111. v-for="item in styleFieldList"
  112. :key="item.fieldName"
  113. :label="item.fieldDescription"
  114. :value="item.fieldName"
  115. >
  116. <span style="float: left">{{ item.fieldDescription }}</span>
  117. <span style="float: right; color: #8492a6; font-size: 13px">{{
  118. item.fieldName
  119. }}</span>
  120. </el-option>
  121. </el-select>
  122. </el-col>
  123. </el-form-item>
  124. <el-form-item label="文本样式">
  125. <el-radio-group v-model="styleFormData.fieldStyleType" size="small">
  126. <el-radio-button :label="0">普通文本</el-radio-button>
  127. <el-radio-button :label="1">标签</el-radio-button>
  128. </el-radio-group>
  129. </el-form-item>
  130. <template v-if="styleFormData.fieldStyleType == 0">
  131. <el-form-item label="字体颜色">
  132. <input
  133. type="color"
  134. :value="styleFormData.fontColor"
  135. @input="selectColors($event, 'fontColor')"
  136. />
  137. </el-form-item>
  138. </template>
  139. <template v-else>
  140. <el-form-item label="标签样式">
  141. <el-switch
  142. v-model="styleFormData.isTagFullBg"
  143. active-text="背景填充"
  144. inactive-text="仅文字"
  145. >
  146. </el-switch>
  147. </el-form-item>
  148. <el-form-item label="标签类型">
  149. <!-- <input
  150. type="color"
  151. :value="styleFormData.tagColor"
  152. @input="selectColors($event, 'tagColor')"
  153. /> -->
  154. <el-select v-model="styleFormData.tagType">
  155. <el-option
  156. v-for="(item, index) in tagTypeList"
  157. :key="index"
  158. :label="item.label"
  159. :value="item.value"
  160. >
  161. </el-option>
  162. </el-select>
  163. <el-tag
  164. class="ml10"
  165. size="normal"
  166. :type="styleFormData.tagType"
  167. :effect="styleFormData.isTagFullBg ? 'dark' : 'light'"
  168. >标签一</el-tag
  169. >
  170. </el-form-item>
  171. </template>
  172. </div>
  173. <div v-show="styleFormData.styleType == 2">
  174. <el-form-item label="字典生效字段" size="normal" prop="styleTable">
  175. <el-col :span="10">
  176. <el-select
  177. v-model="styleFormData.styleTable"
  178. value-key=""
  179. placeholder="请选择表"
  180. clearable
  181. filterable
  182. >
  183. <el-option
  184. v-for="item in tableList"
  185. :key="item.tableName"
  186. :label="item.tableComment"
  187. :value="item.tableName"
  188. >
  189. <span style="float: left">{{ item.tableComment }}</span>
  190. <span style="float: right; color: #8492a6; font-size: 13px">{{
  191. item.tableName
  192. }}</span>
  193. </el-option>
  194. </el-select>
  195. </el-col>
  196. <el-col :span="10">
  197. <el-select
  198. v-model="styleFormData.styleField"
  199. value-key=""
  200. placeholder="请选择字段"
  201. clearable
  202. filterable
  203. >
  204. <el-option
  205. v-for="item in styleFieldList"
  206. :key="item.fieldName"
  207. :label="item.fieldDescription"
  208. :value="item.fieldName"
  209. >
  210. <span style="float: left">{{ item.fieldDescription }}</span>
  211. <span style="float: right; color: #8492a6; font-size: 13px">{{
  212. item.fieldName
  213. }}</span>
  214. </el-option>
  215. </el-select>
  216. </el-col>
  217. </el-form-item>
  218. <el-form-item label="字典" size="normal">
  219. <el-select
  220. v-model="styleFormData.styleCondtion"
  221. placeholder="请选择字典"
  222. filterable
  223. >
  224. <el-option
  225. v-for="item in dictsList"
  226. :key="item.dictType"
  227. :label="item.dictName"
  228. :value="item.dictType"
  229. >
  230. </el-option>
  231. </el-select>
  232. </el-form-item>
  233. </div>
  234. <div v-show="styleFormData.styleType != 2" class="condition-table-wrap">
  235. <span class="table-title">条件编辑</span>
  236. <el-table :data="conditionTableData" style="width: 100%">
  237. <el-table-column label="序号" type="index" width="50">
  238. </el-table-column>
  239. <el-table-column prop="tableName" label="表名" width="150">
  240. <template slot-scope="scope">
  241. <el-select
  242. v-model="scope.row.tableName"
  243. @change="conditionTableChange(scope.row)"
  244. placeholder="请选择"
  245. >
  246. <el-option
  247. v-for="item in tableList"
  248. :key="item.tableName"
  249. :label="item.tableComment"
  250. :value="item.tableName"
  251. >
  252. <span style="float: left">{{ item.tableComment }}</span>
  253. <span
  254. style="float: right; color: #8492a6; font-size: 13px"
  255. >{{ item.tableName }}</span
  256. >
  257. </el-option>
  258. </el-select>
  259. </template>
  260. </el-table-column>
  261. <el-table-column prop="fieldName" label="字段名" width="150">
  262. <template slot-scope="scope">
  263. <el-select v-model="scope.row.fieldName" placeholder="请选择">
  264. <el-option
  265. v-for="item in scope.row.fieldList"
  266. :key="item.fieldName"
  267. :label="item.fieldDescription"
  268. :value="item.fieldName"
  269. >
  270. <span style="float: left">{{ item.fieldDescription }}</span>
  271. <span
  272. style="float: right; color: #8492a6; font-size: 13px"
  273. >{{ item.fieldName }}</span
  274. >
  275. </el-option>
  276. </el-select>
  277. </template>
  278. </el-table-column>
  279. <el-table-column prop="condition" label="条件" width="100">
  280. <template slot-scope="scope">
  281. <el-select v-model="scope.row.condition" placeholder="请选择">
  282. <el-option
  283. v-for="item in conditionList"
  284. :key="item.value"
  285. :label="item.label"
  286. :value="item.value"
  287. >
  288. </el-option>
  289. </el-select>
  290. </template>
  291. </el-table-column>
  292. <el-table-column prop="flagValue" label="参照值" width="100">
  293. <template slot-scope="scope">
  294. <el-input
  295. v-model="scope.row.flagValue"
  296. @input="
  297. scope.row.flagValue = scope.row.flagValue.replace(
  298. /^(0+)|[^\d]+/g,
  299. ''
  300. )
  301. "
  302. ></el-input>
  303. </template>
  304. </el-table-column>
  305. <el-table-column label="操作">
  306. <template slot-scope="scope">
  307. <el-button
  308. size="mini"
  309. type="danger"
  310. icon="el-icon-delete"
  311. @click="deleteConditionItem(scope.$index)"
  312. >删除
  313. </el-button>
  314. </template>
  315. </el-table-column>
  316. </el-table>
  317. <el-button
  318. type="primary"
  319. class="inline-large-button mb10"
  320. icon="el-icon-plus"
  321. size="mini"
  322. style="width: 100%"
  323. @click="addConditionHandler"
  324. >
  325. 添加条件
  326. </el-button>
  327. </div>
  328. </el-form>
  329. <span slot="footer" class="dialog-footer">
  330. <el-button @click="dialogShow = false">取 消</el-button>
  331. <el-button type="primary" @click="saveStyleFormHandler"
  332. >确 定</el-button
  333. >
  334. </span>
  335. </el-dialog>
  336. </div>
  337. </template>
  338. <script>
  339. import { listType } from "@/api/system/tenant/type";
  340. export default {
  341. name: "StyleFormPanel",
  342. props: {
  343. tableFieldList: {
  344. default: [],
  345. type: Array,
  346. },
  347. dragTableStyleList: {
  348. default: [],
  349. type: Array,
  350. },
  351. },
  352. components: {},
  353. data() {
  354. return {
  355. dialogShow: false,
  356. // 表格及字段数据
  357. tableList: [],
  358. isShowFieldList: [],
  359. allFieldList: [],
  360. editIndex: -1,
  361. // 表格样式数据
  362. styleTableData: [],
  363. styleFormData: {
  364. styleName: "",
  365. styleDescription: "",
  366. styleType: 0, //0:行样式 1:字段样式 2:字典样式
  367. styleTable: "", //样式生效的表
  368. styleField: "", //样式生效的字段
  369. tableName: "",
  370. styleCode: "",
  371. styleCondtion: "",
  372. rowBgColor: "", //行背景色
  373. fieldStyleType: 0, //字段样式类型 0:普通文本 1:标签
  374. fontColor: "", //字体颜色
  375. isTagFullBg: false, //tag背景色是否填满
  376. tagType: "",
  377. conditionTableStr: "",
  378. },
  379. styleFormRules: {
  380. styleName: [
  381. { required: true, message: "请输入样式名", trigger: "blur" },
  382. ],
  383. styleTable: [
  384. { validator: this.styleFieldValidator, trigger: "change" },
  385. ],
  386. },
  387. conditionTableData: [
  388. // {
  389. // tableName: "",
  390. // fieldName: "",
  391. // condition: 1, //1:> 2:< 3:= 4:>= 5:<=
  392. // flagValue: 0,
  393. // fieldList: [],
  394. // },
  395. ],
  396. conditionList: [
  397. {
  398. value: 1,
  399. label: ">",
  400. },
  401. {
  402. value: 2,
  403. label: "<",
  404. },
  405. {
  406. value: 3,
  407. label: "=",
  408. },
  409. {
  410. value: 4,
  411. label: ">=",
  412. },
  413. {
  414. value: 5,
  415. label: "<=",
  416. },
  417. ],
  418. tagTypeList: [
  419. {
  420. value: "",
  421. label: "默认",
  422. },
  423. {
  424. value: "success",
  425. label: "成功",
  426. },
  427. {
  428. value: "info",
  429. label: "普通",
  430. },
  431. {
  432. value: "warning",
  433. label: "警告",
  434. },
  435. {
  436. value: "danger",
  437. label: "危险",
  438. },
  439. ],
  440. // 字典列表
  441. dictsList: [],
  442. };
  443. },
  444. computed: {
  445. styleFieldList() {
  446. return this.isShowFieldList.filter(
  447. (item) => item.tableName == this.styleFormData.styleTable
  448. );
  449. },
  450. },
  451. watch: {
  452. tableFieldList: {
  453. handler(nval) {
  454. if (!nval || !nval.length) return;
  455. this.allFieldList = nval;
  456. this.isShowFieldList = nval.filter((item) => item.isShow);
  457. let tempList = nval.map((item) => {
  458. return {
  459. tableName: item.tableName,
  460. tableComment: item.tableComment,
  461. };
  462. });
  463. this.tableList = [];
  464. tempList.forEach((item) => {
  465. let isHas = this.tableList.find(
  466. (it) => it.tableName == item.tableName
  467. );
  468. if (!isHas) {
  469. this.tableList.push(item);
  470. }
  471. });
  472. },
  473. immediate: true,
  474. deep: true,
  475. },
  476. dragTableStyleList: {
  477. handler(nval) {
  478. let res = nval.map((item) => {
  479. let tampItem = JSON.parse(JSON.stringify(item));
  480. let styleCode = JSON.parse(tampItem.styleCode);
  481. let { rowBgColor, fieldStyleType, fontColor, isTagFullBg, tagType } =
  482. styleCode;
  483. let fieldData = tampItem.styleField?.split(".");
  484. Object.assign(tampItem, {
  485. rowBgColor,
  486. fieldStyleType,
  487. fontColor,
  488. isTagFullBg,
  489. tagType,
  490. conditionTableStr: tampItem.styleCondtion,
  491. styleTable: fieldData ? fieldData[0] : "",
  492. styleField: fieldData ? fieldData[1] : "",
  493. });
  494. return tampItem;
  495. });
  496. this.styleTableData = res;
  497. },
  498. immediate: true,
  499. deep: true,
  500. },
  501. },
  502. methods: {
  503. // 添加一条样式数据回调
  504. addDataDialog(index, row) {
  505. this.resetStyleFormData();
  506. this.dialogShow = true;
  507. },
  508. // 重置样式表单
  509. resetStyleFormData() {
  510. Object.assign(this.styleFormData, {
  511. styleName: "",
  512. styleDescription: "",
  513. styleType: 0,
  514. tableName: "",
  515. styleCode: "",
  516. styleCondtion: "",
  517. rowBgColor: "",
  518. fieldStyleType: 0,
  519. fontColor: "",
  520. isTagFullBg: false,
  521. tagType: "",
  522. styleTable: "",
  523. styleField: "",
  524. });
  525. this.conditionTableData = [];
  526. },
  527. //样式表单保存回调
  528. saveStyleFormHandler() {
  529. this.$refs.styleFormDataRef.validate((valid) => {
  530. if (valid) {
  531. // 校验样式生效条件的表格数据
  532. let validateRes = this.validateCondition();
  533. if (!validateRes.flag) {
  534. this.$message.error(validateRes.msg);
  535. return;
  536. }
  537. let tempConditionTableData = this.conditionTableData.map((item) => ({
  538. tableName: item.tableName,
  539. fieldName: item.fieldName,
  540. condition: item.condition,
  541. flagValue: item.flagValue,
  542. }));
  543. this.styleFormData.conditionTableStr = JSON.stringify(
  544. tempConditionTableData
  545. );
  546. let tempFormData = JSON.parse(JSON.stringify(this.styleFormData));
  547. console.log(tempFormData, this.editIndex);
  548. if (this.editIndex != -1) {
  549. //修改
  550. this.$set(this.styleTableData, this.editIndex, tempFormData);
  551. // this.styleTableData[this.editIndex] = tempFormData;
  552. this.editIndex = -1;
  553. } else {
  554. //新增
  555. this.styleTableData.push(tempFormData);
  556. }
  557. console.log(this.styleTableData);
  558. this.dialogShow = false;
  559. } else {
  560. console.log("error submit!!");
  561. return false;
  562. }
  563. });
  564. },
  565. //添加样式判断条件回调
  566. addConditionHandler() {
  567. this.conditionTableData.push({
  568. tableName: "",
  569. fieldName: "",
  570. condition: 1, //1:> 2:< 3:= 4:>= 5:<=
  571. flagValue: 0,
  572. fieldList: [],
  573. });
  574. },
  575. // 颜色改变回调
  576. selectColors(event, tempField) {
  577. console.log(tempField);
  578. this.styleFormData[tempField] = event.target.value;
  579. },
  580. // 条件表改变回调
  581. conditionTableChange(row) {
  582. if (!row.tableName) return;
  583. row.fieldList = this.allFieldList.filter(
  584. (item) => item.tableName == row.tableName
  585. );
  586. },
  587. // 条件表删除回调
  588. deleteConditionItem(index) {
  589. this.conditionTableData.splice(index, 1);
  590. },
  591. // 编辑样式回调
  592. editHandler(row, index) {
  593. this.editIndex = index;
  594. this.styleFormData = JSON.parse(JSON.stringify(row));
  595. console.log(row.conditionTableStr);
  596. if (row.styleType != 2) {
  597. this.conditionTableData = JSON.parse(row.conditionTableStr);
  598. this.conditionTableData.forEach((item) => {
  599. this.conditionTableChange(item);
  600. });
  601. }
  602. this.dialogShow = true;
  603. },
  604. // 删除样式回调
  605. delHandler(index) {
  606. this.styleTableData.splice(index, 1);
  607. },
  608. // 获取保存数据
  609. getSaveData() {
  610. let res = this.styleTableData.map((item) => {
  611. let styleCode = {
  612. rowBgColor: item.rowBgColor,
  613. fieldStyleType: item.fieldStyleType,
  614. fontColor: item.fontColor,
  615. isTagFullBg: item.isTagFullBg,
  616. tagType: item.tagType,
  617. };
  618. return {
  619. styleName: item.styleName,
  620. styleDescription: item.styleDescription,
  621. styleCode: JSON.stringify(styleCode),
  622. styleCondtion:
  623. item.styleType == 2 ? item.styleCondtion : item.conditionTableStr,
  624. styleField: item.styleTable + "." + item.styleField,
  625. styleType: item.styleType,
  626. };
  627. });
  628. return res;
  629. },
  630. // 获取样式条件中的表名和字段
  631. getStyleTableField() {
  632. let res = [];
  633. this.styleTableData
  634. .filter((item) => item.styleType != 2)
  635. .map((item) => {
  636. let tableList = JSON.parse(item.conditionTableStr);
  637. tableList.forEach((val) => {
  638. res.push(val.tableName + "." + val.fieldName);
  639. });
  640. });
  641. return res;
  642. },
  643. // 样式生效字段的表格验证
  644. styleFieldValidator(rule, value, callBack) {
  645. if (this.styleFormData.styleType == 0) return callBack();
  646. let { styleTable, styleField } = this.styleFormData;
  647. if (!styleTable) return callBack(new Error("请选择表格"));
  648. if (!styleField) return callBack(new Error("请选择字段"));
  649. callBack();
  650. },
  651. // 校验样式生效条件
  652. validateCondition() {
  653. let { styleType } = this.styleFormData;
  654. if (styleType == 2) return { flag: true };
  655. let res = {
  656. flag: true,
  657. };
  658. try {
  659. this.conditionTableData.forEach((item) => {
  660. if (!item.tableName || !item.fieldName) {
  661. res.flag = false;
  662. res.msg = "请完善表格数据(表格名/字段名)";
  663. throw new Error("validate error");
  664. }
  665. });
  666. } catch (error) {
  667. if (error != "validate error") console.log(error);
  668. }
  669. return res;
  670. },
  671. },
  672. async mounted() {
  673. let res = await listType(this.addDateRange({ isEnablePaging: false }, []));
  674. this.dictsList = res.rows;
  675. },
  676. };
  677. </script>
  678. <style scoped lang="scss">
  679. .style-wrap {
  680. .condition-table-wrap {
  681. width: 100%;
  682. display: flex;
  683. flex-direction: column;
  684. align-items: center;
  685. .table-title {
  686. margin-bottom: 10px;
  687. font-size: 16px;
  688. font-weight: 600;
  689. }
  690. }
  691. }
  692. </style>