dataInfo.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. <template>
  2. <div class="data-info">
  3. <el-card>
  4. <el-form :model="dataForm" label-width="120px">
  5. <el-form-item label="公式名称:">
  6. <el-input v-model="dataForm.name"></el-input>
  7. </el-form-item>
  8. <el-form-item label="公式:">
  9. <el-input
  10. type="textarea"
  11. v-model="dataForm.formula"
  12. @input="handleFormulaInput"
  13. ref="formulaInput"
  14. ></el-input>
  15. <div style="display: flex; justify-content: flex-end">
  16. <!-- <el-button style="margin-top: 10px" @click="InsertTableData"
  17. >插入表格数据</el-button
  18. > -->
  19. <el-button
  20. style="margin-top: 10px"
  21. type="primary"
  22. @click="InsertModule"
  23. >插入模块变量</el-button
  24. >
  25. </div>
  26. <div class="intro">
  27. 公式说明:
  28. <div>
  29. 格式一:[T][模块引用名][属性引用名] <span>*</span>其中
  30. [T]表示的是模块引用。
  31. </div>
  32. <div>目前仅支持+、-、*、/ 四种计算符合</div>
  33. <div>示例: [T][模块01][attr01]+[T][模块01][attr02]</div>
  34. <div>
  35. 格式二:[T][模块引用名][属性引用名]
  36. IF(判断条件,true值,false值)<span>*</span>其中
  37. [T]表示的是模块引用。
  38. </div>
  39. <div>
  40. 示例: [T][图文][测试1]+IF([T][图文][测试1]>30,[T][图文][测试2],11)
  41. </div>
  42. <div>
  43. 嵌套示例: [T][图文][测试1] + IF([T][图文][测试2] > 50,
  44. IF([T][图文][测试1] > 30, [T][图文][测试3], 20),
  45. IF([T][图文][测试3] > 40, 15, [T][图文][测试2]) )
  46. </div>
  47. </div>
  48. </el-form-item>
  49. <el-form-item label="保留小数点:">
  50. <el-input
  51. v-model.number="dataForm.point"
  52. type="number"
  53. min="0"
  54. max="4"
  55. :step="1"
  56. @input="validatePoint"
  57. ></el-input>
  58. </el-form-item>
  59. <el-form-item label="介绍:">
  60. <el-input type="textarea" v-model="dataForm.intro"></el-input>
  61. </el-form-item>
  62. <el-form-item label="公式状态:">
  63. <el-select
  64. v-model="dataForm.status"
  65. placeholder="请选择状态"
  66. size="large"
  67. style="width: 100%"
  68. >
  69. <el-option
  70. v-for="item in statusOptions"
  71. :key="item.value"
  72. :label="item.label"
  73. :value="item.value"
  74. />
  75. </el-select>
  76. </el-form-item>
  77. </el-form>
  78. </el-card>
  79. <div style="text-align: right; margin-top: 20px">
  80. <el-button type="warning" @click="btnSave">确认保存</el-button>
  81. </div>
  82. <el-dialog
  83. :visible.sync="variablesVisible"
  84. append-to-body
  85. width="300"
  86. custom-class="prod-verify"
  87. :title="title"
  88. :close-on-click-modal="false"
  89. @close="close"
  90. >
  91. <el-form :model="insertForm" :rules="insertRules" ref="insertRef">
  92. <el-form-item label="模块名称:">
  93. <el-select
  94. v-model="insertForm.moduleName"
  95. placeholder="请选择模块"
  96. size="large"
  97. style="width: 100%"
  98. @change="changeModule"
  99. >
  100. <el-option
  101. v-for="(item, index) in list"
  102. :key="`${item.id}-${index}`"
  103. :label="item.name"
  104. :value="item.attrs"
  105. />
  106. </el-select>
  107. </el-form-item>
  108. <el-form-item label="属性名称:" prop="Variable">
  109. <el-select
  110. v-model="insertForm.Variable"
  111. placeholder="请选择属性"
  112. size="large"
  113. style="width: 100%"
  114. >
  115. <el-option
  116. v-for="(item, index) in attrList"
  117. :key="`${item.id}-${index}`"
  118. :label="item.name"
  119. :value="item.id"
  120. />
  121. </el-select>
  122. </el-form-item>
  123. </el-form>
  124. <span slot="footer" class="dialog-footer">
  125. <el-button type="warning" @click="btnInster">确认插入</el-button>
  126. </span>
  127. </el-dialog>
  128. <el-dialog
  129. :visible.sync="tableDataVisible"
  130. append-to-body
  131. width="400"
  132. custom-class="prod-verify"
  133. title="插入表格数据"
  134. :close-on-click-modal="false"
  135. @close="close"
  136. >
  137. <div class="com-formual">
  138. <el-form>
  139. <el-form-item>
  140. <el-select
  141. v-model="tableCode"
  142. placeholder="请选择状态"
  143. @change="onChangeTab"
  144. size="large"
  145. style="width: 100%"
  146. >
  147. <el-option
  148. v-for="(item, index) in tableList"
  149. :key="item.id"
  150. :label="item.name"
  151. :value="index"
  152. />
  153. </el-select>
  154. </el-form-item>
  155. <el-form-item style="min-height: 500px" v-if="fileLoadStatus">
  156. <div
  157. id="luckysheets"
  158. ref="luckysheets"
  159. style="width: 100%; height: 500px"
  160. ></div>
  161. </el-form-item>
  162. </el-form>
  163. </div>
  164. </el-dialog>
  165. <el-dialog
  166. :visible.sync="showConfirm"
  167. title="数据确认"
  168. width="500"
  169. align-center
  170. :append-to-body="true"
  171. :close-on-click-modal="false"
  172. >
  173. <div>当前工作表:{{ position.sheet }}</div>
  174. <div>当前取值:{{ position.value }}</div>
  175. <template #footer>
  176. <div class="dialog-footer">
  177. <el-button @click="showConfirm = false">关闭</el-button>
  178. <el-button type="primary" @click="onConfirm">确认插入</el-button>
  179. </div>
  180. </template>
  181. </el-dialog>
  182. </div>
  183. </template>
  184. <script>
  185. import { createFormula, updateFormula, getFormulaInfo } from "@/api/formula";
  186. import { searchSourceData, deleteSourceData } from "@/api/sourceData";
  187. import LuckyExcel from "luckyexcel";
  188. export default {
  189. emits: ["onClose"],
  190. props: {
  191. id: {
  192. type: Number,
  193. default: 0,
  194. },
  195. list: {
  196. type: Array,
  197. default: [],
  198. },
  199. },
  200. watch: {
  201. id: {
  202. handler(newVal, oldVal) {
  203. if (newVal == null) return;
  204. if (newVal == 0) {
  205. this.resetForm();
  206. } else {
  207. // 添加条件以确保在id相同但需要重新获取数据时也能触发
  208. if (newVal !== oldVal || this.dataForm.id !== newVal) {
  209. this.getInfo(newVal);
  210. }
  211. }
  212. },
  213. immediate: true,
  214. },
  215. list: {
  216. handler(newValue, oldValue) {
  217. console.log("list changed:", newValue);
  218. },
  219. immediate: true,
  220. deep: true,
  221. },
  222. },
  223. data() {
  224. return {
  225. activeName: "base",
  226. currentCategory: [],
  227. allCategories: [],
  228. dataForm: {
  229. id: 0,
  230. name: "",
  231. formula: "",
  232. intro: "",
  233. status: 5,
  234. use_status: 5,
  235. params: "[]",
  236. point: 0,
  237. },
  238. statusOptions: [
  239. {
  240. value: "",
  241. label: "请选择状态",
  242. },
  243. {
  244. value: 5,
  245. label: "使用中",
  246. },
  247. {
  248. value: 6,
  249. label: "已停用",
  250. },
  251. ],
  252. variablesVisible: false,
  253. title: "",
  254. insertForm: {
  255. moduleName: "",
  256. Variable: "",
  257. },
  258. insertRules: {
  259. Variable: [
  260. { required: true, message: "请选择变量", trigger: "change" },
  261. ],
  262. },
  263. tableDataVisible: false,
  264. tableCode: "",
  265. tableList: [],
  266. showConfirm: false,
  267. fileLoadStatus: false,
  268. position: {
  269. tb: "",
  270. c: 0,
  271. r: 0,
  272. sheet: "",
  273. value: "",
  274. },
  275. attrList: [],
  276. };
  277. },
  278. mounted() {
  279. let _this = this;
  280. this.initTableList();
  281. },
  282. methods: {
  283. validatePoint(value) {
  284. const intValue = parseInt(value);
  285. if (isNaN(intValue) || intValue < 0 || intValue > 4) {
  286. this.dataForm.point = "";
  287. } else {
  288. this.dataForm.point = intValue;
  289. }
  290. },
  291. /* 关闭 */
  292. close() {
  293. this.insertForm = {};
  294. },
  295. /* */
  296. handleFormulaInput(value) {
  297. // 更新 dataForm.formula 的值
  298. this.dataForm.formula = value;
  299. },
  300. resetForm() {
  301. this.dataForm = {
  302. id: 0,
  303. name: "",
  304. formula: "",
  305. intro: "",
  306. status: 5,
  307. use_status: 5,
  308. params: "[]",
  309. point: 0,
  310. };
  311. },
  312. btnSave(e) {
  313. let _this = this;
  314. const saveAction = _this.dataForm.id > 0 ? updateFormula : createFormula;
  315. saveAction(_this.dataForm)
  316. .then((res) => {
  317. _this.$message.success(
  318. _this.dataForm.id > 0 ? "公式更新成功" : "公式创建成功"
  319. );
  320. _this.$emit("onClose", true); // Pass a boolean to indicate successful save
  321. // 添加这行来强制重新获取数据
  322. _this.getInfo(_this.dataForm.id);
  323. })
  324. .catch((error) => {
  325. console.error("保存失败:", error);
  326. _this.$message.error("保存失败,请重试");
  327. });
  328. },
  329. //产品详情
  330. getInfo(id) {
  331. let _this = this;
  332. let par = {
  333. id: id,
  334. };
  335. getFormulaInfo(par).then((res) => {
  336. if (!res) return;
  337. if (res.status != 200) return;
  338. _this.dataForm = res.data;
  339. });
  340. },
  341. onChangeStatus(e) {
  342. this.dataForm.status = e;
  343. },
  344. //修改分类信息
  345. onChangeCategory(e) {
  346. let _this = this;
  347. _this.dataForm.categoryId = e;
  348. },
  349. /* 插入模块变量 */
  350. InsertModule() {
  351. this.variablesVisible = true;
  352. this.title = "插入模块变量";
  353. },
  354. extractChineseTemplates(content) {
  355. const templateRegex = /\{\{(.*?)\}\}/g;
  356. const chineseRegex = /[\u4e00-\u9fa5]/;
  357. let match;
  358. const chineseTemplates = [];
  359. while ((match = templateRegex.exec(content)) !== null) {
  360. if (chineseRegex.test(match[1])) {
  361. chineseTemplates.push(match[1].trim());
  362. }
  363. }
  364. return chineseTemplates;
  365. },
  366. processContent(val) {
  367. console.log(val);
  368. if (val && val.content) {
  369. const chineseTemplates = this.extractChineseTemplates(val.content);
  370. console.log("Chinese templates:", chineseTemplates);
  371. if (val.attrs && Array.isArray(val.attrs)) {
  372. this.attrList = val.attrs.filter((el) =>
  373. chineseTemplates.includes(el.id)
  374. );
  375. }
  376. } else {
  377. this.attrList = [];
  378. }
  379. },
  380. /* 模块名称 */
  381. changeModule(value) {
  382. const selectedIndex = this.list.findIndex(
  383. (option) => option.attrs === value
  384. );
  385. this.processContent(this.list[selectedIndex]);
  386. //this.attrList = value; // 假设 attrs 属性包含了属性列表
  387. },
  388. /* 插入变量 */
  389. btnInster() {
  390. this.$refs.insertRef.validate((valid) => {
  391. if (valid) {
  392. const selectedModule = this.list.find(
  393. (module) => module.attrs === this.insertForm.moduleName
  394. );
  395. if (selectedModule) {
  396. const moduleName = selectedModule.name;
  397. const variableName = this.attrList.find(
  398. (attr) => attr.id === this.insertForm.Variable
  399. )?.name;
  400. if (variableName) {
  401. const insertText = `[T][${moduleName}][${variableName}]`;
  402. this.dataForm.formula += insertText;
  403. this.variablesVisible = false; // 关闭对话框
  404. this.$message.success("变量插入成功");
  405. } else {
  406. this.$message.error("无法找到选中的变量");
  407. }
  408. } else {
  409. this.$message.error("无法找到选中的模块");
  410. }
  411. } else {
  412. /* this.$message.error("请选择变量!"); */
  413. return false;
  414. }
  415. });
  416. },
  417. /* 插入表格数据 */
  418. InsertTableData() {
  419. this.tableDataVisible = true;
  420. },
  421. onConfirm(e) {
  422. this.showConfirm = false;
  423. const insertText = `[R][${this.position.tb}][${this.position.sheet}][${
  424. this.position.r + 1
  425. },${this.position.c + 1}]`;
  426. this.dataForm.formula += insertText;
  427. this.tableDataVisible = false;
  428. this.$message.success("表格数据插入成功");
  429. this.insertForm = {
  430. moduleName: {},
  431. Variable: "",
  432. };
  433. },
  434. onChangeTab(e) {
  435. let _this = this;
  436. let item = _this.tableList[e];
  437. _this.fileLoadStatus = true;
  438. item.sourceData = JSON.parse(item.source_data);
  439. console.log(item.sourceData.exportJson.sheets);
  440. _this.position.tb = item.code;
  441. _this.$nextTick(() => {
  442. luckysheet.destroy();
  443. luckysheet.create({
  444. container: "luckysheets",
  445. data: item.sourceData.exportJson.sheets,
  446. lang: "zh",
  447. showinfobar: false, // 是否显示顶部信息栏
  448. showstatisticBar: false, // 是否显示底部计数栏
  449. sheetBottomConfig: false, // sheet页下方的添加行按钮和回到顶部按钮配置
  450. allowEdit: false, // 是否允许前台编辑
  451. enableAddRow: false, // 是否允许增加行
  452. enableAddCol: false, // 是否允许增加列
  453. sheetFormulaBar: false, // 是否显示公式栏
  454. enableAddBackTop: false, // 返回头部按钮
  455. showsheetbar: true, // 是否显示底部sheet页按钮
  456. enableAddRow: false, //允许添加行
  457. showsheetbarConfig: {
  458. add: false,
  459. menu: false,
  460. },
  461. hook: {
  462. cellMousedown: function (cell, position, sheetFile, ctx) {
  463. _this.position.sheet = sheetFile.name;
  464. _this.position.r = position.r;
  465. _this.position.c = position.c;
  466. if (cell.v) {
  467. _this.position.value = cell.v;
  468. } else {
  469. _this.position.value = "";
  470. cell.ct.s.map((res) => {
  471. _this.position.value += res.v;
  472. });
  473. }
  474. _this.showConfirm = true;
  475. },
  476. },
  477. });
  478. });
  479. },
  480. initTableList() {
  481. let _this = this;
  482. searchSourceData({ page: 1, pageSize: 999, status: 5 }).then((res) => {
  483. if (res.status != 200) return;
  484. _this.tableList = res.data.dataList;
  485. });
  486. },
  487. },
  488. };
  489. </script>
  490. <style lang="scss">
  491. @import "./dataInfo.scss";
  492. </style>