conditionDia.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <template>
  2. <div v-dialogDrag v-if="isOpenDialog">
  3. <div class="condition-dialog el-dialog" style="width:522px">
  4. <div class="header el-dialog__header">
  5. <span>{{
  6. $t("MixSheet.conditional_format") + "-" + chooseTitleObj[chooseType]
  7. }}</span>
  8. <i class="el-icon-close" @click="cancelHandle" />
  9. </div>
  10. <div class="main" :style="{'padding-top':chooseType==6?'30px':'10px'}">
  11. <el-form v-if="chooseType != 6" hide-required-asterisk :model="ruleForm" :rules="rules" ref="ruleForm"
  12. class="demo-ruleForm" label-position="top">
  13. <el-form-item :label="chooseTitleObj[chooseType]">
  14. <div class="flex-align value-box">
  15. <el-form-item label-width="0" label="" :rules="chooseType == 5 ? rules.fsrqval : rules.LeftValue"
  16. prop="LeftValue">
  17. <el-select v-if="chooseType == 5" style="width:100%" v-model="ruleForm.LeftValue"
  18. :placeholder="$t('MixSheet.please_choose')">
  19. <el-option v-for="item in dateSel" :key="item.value" :label="item.label" :value="item.value">
  20. </el-option>
  21. </el-select>
  22. <el-input :placeholder="$t('MixSheet.enter_number')" v-else style="width:100%"
  23. @focus="momentRef = 'LeftValueRef'" ref="LeftValueRef" v-model="ruleForm.LeftValue"></el-input>
  24. </el-form-item>
  25. <template v-if="chooseType == 3">
  26. <span style="margin:0 9px;">{{ $t("MixSheet.and") }}</span>
  27. <el-form-item label-width="0" label="" prop="RightValue">
  28. <el-input :placeholder="$t('MixSheet.enter_number')" @focus="momentRef = 'RightValueRef'"
  29. ref="RightValueRef" style="width:100%" v-model="ruleForm.RightValue"></el-input>
  30. </el-form-item>
  31. </template>
  32. </div>
  33. </el-form-item>
  34. <el-form-item :label="$t('MixSheet.set_to')" prop="Remark">
  35. <el-select style="width:100%" @change="changeColorSel" v-model="ruleForm.Remark"
  36. :placeholder="$t('MixSheet.please_set')">
  37. <el-option v-for="color in colorSelect" :key="color.label" :label="color.label"
  38. :value="color.value"></el-option>
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item :label="$t('MixSheet.apply_selection')" prop="Scope">
  42. <el-input :placeholder="$t('MixSheet.please_c_or_i')" @focus="momentRef = 'ScopeRef'" ref="ScopeRef"
  43. style="width:100%" v-model="ruleForm.Scope"></el-input>
  44. </el-form-item>
  45. <el-form-item label-position="left" v-if="ruleForm.Remark === '自定义'" label="" label-width="0"
  46. prop="BackgroundColor">
  47. <div class="flex-align">
  48. <div style="margin-right:10px;">
  49. {{ $t("MixSheet.background_color") }}
  50. </div>
  51. <el-color-picker v-model="ruleForm.BackgroundColor" show-alpha></el-color-picker>
  52. <div style="margin:0 10px 0 40px;">
  53. {{ $t("MixSheet.text_color") }}
  54. </div>
  55. <el-color-picker v-model="ruleForm.FontColor" show-alpha></el-color-picker>
  56. </div>
  57. </el-form-item>
  58. </el-form>
  59. <div class="dialog-table-box" v-else>
  60. <el-table :data="diaRuleList" :header-cell-style="{
  61. background: '#F6F7FA',
  62. 'text-align': 'center',
  63. }" border style="width: 100%">
  64. <el-table-column align="center" :label="$t('MixSheet.rule')">
  65. <template slot-scope="scope">
  66. <template v-if="scope.row.RuleType != 5">
  67. {{ chooseTitleObj[scope.row.RuleType] }}{{ scope.row.LeftValue }}<span
  68. v-if="scope.row.RuleType == 3">{{
  69. $t("MixSheet.and") }}{{ scope.row.RightValue }}</span>
  70. </template>
  71. <template v-else>
  72. {{ dateSel.find(el=>el.value==scope.row.LeftValue).label }}
  73. </template>
  74. </template>
  75. </el-table-column>
  76. <el-table-column align="center" prop="ScopeShow" :label="$t('MixSheet.apply_selection')">
  77. </el-table-column>
  78. <el-table-column align="center" :label="$t('MixSheet.operation')" width="150">
  79. <template slot-scope="scope">
  80. <el-button @click="handleEdit(scope.row)" type="text" size="small">{{ $t("MixSheet.edit") }}</el-button>
  81. <el-button style="color: #f56c6c" @click="handleDelete(scope.row, scope.$index)" type="text"
  82. size="small">{{ $t("MixSheet.delete") }}</el-button>
  83. </template>
  84. </el-table-column>
  85. </el-table>
  86. </div>
  87. </div>
  88. <section class="bot" v-if="chooseType != 6">
  89. <el-button type="primary" plain @click="cancelHandle">{{
  90. $t("MixSheet.cancel_btn")
  91. }}</el-button>
  92. <el-button type="primary" @click="saveHandle">{{
  93. $t("MixSheet.save_btn")
  94. }}</el-button>
  95. </section>
  96. </div>
  97. </div>
  98. </template>
  99. <script>
  100. import { dataBaseInterface } from "@/api/api.js";
  101. export default {
  102. props: {
  103. chooseCell: {
  104. type: Object,
  105. },
  106. },
  107. watch: {
  108. chooseCell: {
  109. handler(nval) {
  110. if (nval && this.momentRef) {
  111. // console.log(nval, this.momentRef);
  112. if (this.momentRef == "ScopeRef") {
  113. this.chooseArray = Array.isArray(nval) ? nval : [nval];
  114. this.formatXq(this.chooseArray);
  115. } else {
  116. // console.log(!Array.isArray(nval));
  117. if (!Array.isArray(nval)) {
  118. this.formatXq(
  119. [nval],
  120. this.momentRef === "LeftValueRef" ? "LeftValue" : "RightValue"
  121. );
  122. }
  123. }
  124. }
  125. },
  126. deep: true,
  127. },
  128. },
  129. computed: {
  130. colorSelect() {
  131. return [
  132. {
  133. label: this.$t("MixSheet.lrf_drt"),
  134. value: "rgb(235, 49, 34)-rgb(255, 235, 235)", //前为文本颜色,后为填充色
  135. },
  136. {
  137. label: this.$t("MixSheet.yf_dyt"),
  138. value: "rgb(255, 175, 1)-rgb(255, 248, 216)",
  139. },
  140. {
  141. label: this.$t("MixSheet.gf_dgt"),
  142. value: "rgb(10, 147, 47)-rgb(231, 255, 231)",
  143. },
  144. {
  145. label: this.$t("MixSheet.lrf"),
  146. value: "-rgb(252,157,154)",
  147. },
  148. {
  149. label: this.$t("MixSheet.rt"),
  150. value: "rgb(255, 0, 0)-",
  151. },
  152. {
  153. label: this.$t("MixSheet.custom"),
  154. value: "自定义",
  155. },
  156. ];
  157. },
  158. dateSel() {
  159. return [
  160. {
  161. label: this.$t("MixSheet.today"),
  162. value: "today",
  163. },
  164. {
  165. label: this.$t("MixSheet.tomorrow"),
  166. value: "tomorrow",
  167. },
  168. {
  169. label: this.$t("MixSheet.last_7_days"),
  170. value: "last7days",
  171. },
  172. {
  173. label: this.$t("MixSheet.last_week"),
  174. value: "lastweek",
  175. },
  176. {
  177. label: this.$t("MixSheet.this_week"),
  178. value: "thisweek",
  179. },
  180. {
  181. label: this.$t("MixSheet.next_week"),
  182. value: "nextweek",
  183. },
  184. {
  185. label: this.$t("MixSheet.last_month"),
  186. value: "lastmonth",
  187. },
  188. {
  189. label: this.$t("MixSheet.this_month"),
  190. value: "thismonth",
  191. },
  192. {
  193. label: this.$t("MixSheet.next_month"),
  194. value: "nextmonth",
  195. },
  196. ];
  197. },
  198. chooseTitleObj() {
  199. return {
  200. 1: this.$t("MixSheet.greater_than"),
  201. 2: this.$t("MixSheet.less_than"),
  202. 3: this.$t("MixSheet.between"),
  203. 4: this.$t("MixSheet.equal_to"),
  204. 5: this.$t("MixSheet.occurrence_date"),
  205. 6: this.$t("MixSheet.manage_rules"),
  206. };
  207. },
  208. rules() {
  209. const validateValue = (rule, value, callback) => {
  210. const regex1 = /^\$[A-Z]+\$[1-9][0-9]*$/;
  211. if (value === "") {
  212. callback(new Error(this.$t("MixSheet.enter_number")));
  213. } else if (regex1.test(value) || Number.isFinite(+value)) {
  214. callback();
  215. } else {
  216. callback(new Error(this.$t("MixSheet.parameter_error")));
  217. }
  218. };
  219. const validateScope = (rule, value, callback) => {
  220. const regex1 = /^\$[A-Z]+\$[1-9][0-9]*$/;
  221. const regex2 = /^\$[A-Z]+\$[1-9][0-9]*:\$[A-Z]+\$[1-9][0-9]*$/;
  222. if (value === "") {
  223. callback(new Error(this.$t("MixSheet.please_c_or_i")));
  224. } else if (regex1.test(value) || regex2.test(value)) {
  225. callback();
  226. } else {
  227. callback(new Error(this.$t("MixSheet.apply_selection_error")));
  228. }
  229. };
  230. return {
  231. fsrqval: [
  232. {
  233. required: true,
  234. message: this.$t("MixSheet.please_choose"),
  235. trigger: "change",
  236. },
  237. ],
  238. LeftValue: [
  239. {
  240. required: true,
  241. message: this.$t("MixSheet.enter_number"),
  242. trigger: ["blur", "change"],
  243. },
  244. { validator: validateValue, trigger: "blur" },
  245. ],
  246. RightValue: [
  247. {
  248. required: true,
  249. message: this.$t("MixSheet.enter_number"),
  250. trigger: ["blur", "change"],
  251. },
  252. { validator: validateValue, trigger: "blur" },
  253. ],
  254. Remark: [
  255. {
  256. required: true,
  257. message: this.$t("MixSheet.please_choose"),
  258. trigger: "change",
  259. },
  260. ],
  261. Scope: [
  262. {
  263. required: true,
  264. message: this.$t("MixSheet.please_c_or_i"),
  265. trigger: ["blur", "change"],
  266. },
  267. { validator: validateScope, trigger: "blur" },
  268. ],
  269. };
  270. },
  271. },
  272. data() {
  273. return {
  274. ExcelInfoId: 0,
  275. diaRuleList: [],
  276. ExcelRuleMappingId: 0,
  277. chooseType: "",
  278. isOpenDialog: false,
  279. chooseArray: [],
  280. ruleForm: {
  281. LeftValue: "",
  282. RightValue: "",
  283. Remark: "rgb(235, 49, 34)-rgb(255, 235, 235)",
  284. FontColor: "rgb(235, 49, 34)",
  285. BackgroundColor: "rgb(255, 235, 235)",
  286. Scope: "",
  287. },
  288. };
  289. },
  290. methods: {
  291. // 编辑规则
  292. async handleEdit(row) {
  293. this.$nextTick(() => {
  294. this.ruleForm = JSON.parse(
  295. JSON.stringify({ ...row, Scope: row.ScopeShow })
  296. );
  297. this.chooseType = row.RuleType;
  298. this.ExcelRuleMappingId = row.ExcelInfoRuleMappingId;
  299. });
  300. },
  301. // 删除规则
  302. async handleDelete(row, index) {
  303. // console.log(index);
  304. const res = await dataBaseInterface.excelRuleDelete({
  305. ExcelRuleMappingId: row.ExcelInfoRuleMappingId,
  306. });
  307. // console.log(res);
  308. if (res.Ret !== 200) return;
  309. this.diaRuleList.splice(index, 1);
  310. this.$message({
  311. message: this.$t("MixSheet.delete_text"),
  312. type: "success",
  313. });
  314. this.$emit("deleteRule", row);
  315. },
  316. // 切换颜色选择
  317. changeColorSel(val) {
  318. const colorArr = val.split("-");
  319. this.ruleForm.FontColor = val != "自定义" ? colorArr[0] : "";
  320. this.ruleForm.BackgroundColor = val != "自定义" ? colorArr[1] : "";
  321. },
  322. // 保存
  323. saveHandle() {
  324. this.momentRef = "";
  325. this.$refs["ruleForm"].validate(async (valid) => {
  326. if(this.chooseType == 3 && (+this.ruleForm.LeftValue >= +this.ruleForm.RightValue))
  327. return this.$message.warning('介于规则不允许前值大于等于后值');
  328. if (valid) {
  329. const params = {
  330. ...this.ruleForm,
  331. ExcelRuleMappingId: +this.ExcelRuleMappingId,
  332. ExcelInfoId: +this.ExcelInfoId,
  333. RuleType: +this.chooseType,
  334. LeftValueType:
  335. this.chooseType == 5
  336. ? 1
  337. : Number.isFinite(+this.ruleForm.LeftValue)
  338. ? 1
  339. : 2,
  340. RightValueType: this.ruleForm.RightValue
  341. ? Number.isFinite(+this.ruleForm.RightValue)
  342. ? 1
  343. : 2
  344. : 0,
  345. };
  346. let res = "";
  347. if (this.ExcelRuleMappingId) {
  348. res = await dataBaseInterface.excelRuleEdit(params);
  349. } else {
  350. res = await dataBaseInterface.excelRuleAdd(params);
  351. }
  352. // console.log(res);
  353. if (res.Ret !== 200) return;
  354. this.$message({
  355. message: this.ExcelRuleMappingId
  356. ? this.$t("MixSheet.edit_text")
  357. : this.$t("MixSheet.add_text"),
  358. type: "success",
  359. });
  360. if (this.ExcelRuleMappingId) {
  361. this.$emit("editRule", { ...params, ScopeShow: params.Scope });
  362. } else {
  363. this.$emit("changeRule");
  364. }
  365. this.cancelHandle();
  366. } else {
  367. return false;
  368. }
  369. });
  370. },
  371. // 打开弹框
  372. openDialog(type, array, ruleList, id) {
  373. if (this.isOpenDialog) {
  374. this.cancelHandle();
  375. }
  376. this.ExcelRuleMappingId = 0;
  377. this.chooseType = type;
  378. this.isOpenDialog = true;
  379. this.chooseArray = array;
  380. this.diaRuleList = ruleList;
  381. this.ExcelInfoId = id;
  382. if (type != 6) {
  383. this.formatXq(this.chooseArray);
  384. }
  385. },
  386. formatXq(array, key = "Scope") {
  387. // console.log(array, key);
  388. if (array.length < 2) {
  389. let str = "$" + array[0].colIndex + "$" + array[0].rowIndex;
  390. this.$set(this.ruleForm, key, str);
  391. } else {
  392. let str = "";
  393. array.forEach((el, index) => {
  394. if (index === 0 || index == array.length - 1) {
  395. str +=
  396. "$" +
  397. array[index].colIndex +
  398. "$" +
  399. array[index].rowIndex +
  400. (index === 0 ? ":" : "");
  401. }
  402. });
  403. this.$set(this.ruleForm, key, str);
  404. }
  405. },
  406. cancelHandle() {
  407. this.momentRef = "";
  408. this.$refs.ruleForm && this.$refs.ruleForm.resetFields();
  409. this.isOpenDialog = false;
  410. this.ruleForm = {
  411. LeftValue: "",
  412. RightValue: "",
  413. Remark: "rgb(235, 49, 34)-rgb(255, 235, 235)",
  414. FontColor: "rgb(235, 49, 34)",
  415. BackgroundColor: "rgb(255, 235, 235)",
  416. };
  417. },
  418. handleClickOutside(event) {
  419. let _this = this;
  420. // 检查点击是否发生在el-input外
  421. if (
  422. _this.$refs[_this.momentRef] &&
  423. !_this.$refs.LeftValueRef.$el.contains(event.target)
  424. ) {
  425. // 如果是,则将焦点设置到当前el-input
  426. _this.$refs[_this.momentRef].focus();
  427. }
  428. },
  429. },
  430. mounted() {
  431. // 监听全局点击事件
  432. document.addEventListener("click", this.handleClickOutside);
  433. },
  434. beforeDestroy() {
  435. // 组件销毁前移除监听
  436. document.removeEventListener("click", this.handleClickOutside);
  437. },
  438. };
  439. </script>
  440. <style lang="scss" scoped>
  441. @import "~@/styles/theme-vars.scss";
  442. .condition-dialog {
  443. background: #fff;
  444. position: fixed;
  445. top: 20%;
  446. left: 45%;
  447. border-radius: 2px;
  448. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  449. z-index: 9999;
  450. .header {
  451. font-size: 16px;
  452. background: $theme-color;
  453. color: #fff;
  454. padding: 15px;
  455. display: flex;
  456. align-content: center;
  457. justify-content: space-between;
  458. .el-icon-close {
  459. font-size: 20px;
  460. cursor: pointer;
  461. }
  462. }
  463. .main {
  464. padding: 30px 60px;
  465. max-height: calc(100vh - 350px);
  466. min-height: 300px;
  467. overflow-y: auto;
  468. .main-top {
  469. margin-bottom: 20px;
  470. .right-form-item {
  471. .el-form-item__error {
  472. padding-left: 20px;
  473. }
  474. }
  475. }
  476. }
  477. .bot {
  478. display: flex;
  479. justify-content: center;
  480. margin: 30px 0;
  481. }
  482. .flex-align {
  483. display: flex;
  484. align-items: center;
  485. }
  486. }
  487. </style>
  488. <style lang="scss">
  489. .condition-dialog {
  490. .value-box {
  491. .el-form-item {
  492. flex: 1;
  493. }
  494. }
  495. }
  496. </style>