main.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. const ComponentPathMap = new Map();
  2. const ComponentNameMap = new Map();
  3. // 商品格式用到的
  4. var old_attr = '' // 每次当属性获得焦点时都会获取输入框内的值,保存于此
  5. var old_attr_value = '' // 每次当属性值获得焦点时都会获取输入框内的值,保存于此
  6. let first_column_rule = [] // 第一列使用相同的合并规则 (不能存在data中)
  7. new Vue({
  8. el: "#app",
  9. delimiters: ["[[", "]]"],
  10. data() {
  11. return {
  12. currentShowPage: null,
  13. pages: {},
  14. showComponentName: "",
  15. componentLoaded: false,
  16. http_url:httpUrl,
  17. // 防止快速点击保存
  18. saveStatus:true
  19. };
  20. },
  21. created() {
  22. this.fetchData(GetGoodsDataUrl).then((pageGroup) => {
  23. const pages = {};
  24. let loadedComponentCount = 0;
  25. let componentCount = 0;
  26. pageGroup.forEach((page) => {
  27. const childrens = [];
  28. page.column.forEach((columnItem) => {
  29. //* 把页面的组名和页面的名称组成一个路径
  30. let path = columnItem.group + "/" + columnItem.template_code;
  31. if (!ComponentPathMap.has(columnItem.page_path)) {
  32. //* 生成一个页面路径别名。如果其他页面也是同样的路径就会使用同样的别名,把别名和页面路径连在起义就是加载页面组件js文件的路径
  33. const pageAlias = "page" + ComponentPathMap.size;
  34. ComponentPathMap.set(columnItem.page_path, pageAlias);
  35. require.config({
  36. paths: {
  37. [pageAlias]: columnItem.page_path,
  38. },
  39. });
  40. }
  41. path = ComponentPathMap.get(columnItem.page_path) + "/" + path;
  42. const componentName = "Component" + Date.now() + Math.round(Math.random() * 1000); //* 生成组件名称
  43. ComponentNameMap.set(componentName, path);
  44. childrens.push({
  45. attr_hide:columnItem.attr_hide,
  46. title: columnItem.title,
  47. name: columnItem.template_code,
  48. path,
  49. componentName,
  50. data: columnItem.data,
  51. widget_key: columnItem.widget_key,
  52. group: page.group,
  53. });
  54. componentCount++; //* 每加载一个组件就会递增组件数量,用于判断是否组件是否加载完成
  55. this.loadComponent(componentName).then((res) => {
  56. loadedComponentCount++;
  57. //* 当所有组件文件加载完成才会显示页面,因为vue的ref需要组件加载完后才能获取
  58. if (loadedComponentCount === componentCount) {
  59. this.componentLoaded = true;
  60. }
  61. });
  62. });
  63. pages[page.group] = {
  64. key: page.group,
  65. title: page.title,
  66. childrens,
  67. };
  68. });
  69. this.pages = pages;
  70. this.currentShowPage = Object.keys(pages)[0];
  71. });
  72. },
  73. methods: {
  74. fetchData(URL, requestParams) {
  75. return new Promise((resolve, reject) => {
  76. this.$http
  77. .post(URL, requestParams)
  78. .then(function (response) {
  79. return response.json();
  80. })
  81. .then(({ result, data, msg }) => {
  82. if (result == 0) {
  83. this.$message({
  84. message: msg,
  85. type: "error",
  86. });
  87. reject({ result, data, msg });
  88. }
  89. resolve(data);
  90. })
  91. .catch((err) => {
  92. reject(err);
  93. });
  94. });
  95. },
  96. loadComponent(name) {
  97. let conponentPath = ComponentNameMap.get(name);
  98. if (!conponentPath) conponentPath = name;
  99. return new Promise((resolve, reject) => {
  100. const pageLoading = this.$loading({
  101. target: ".goods-page_main",
  102. text: "页面加载中",
  103. });
  104. require([conponentPath], (options) => {
  105. // 注册组件
  106. this.$options.components[name] = options;
  107. if (options && options.style) {
  108. const styleEl = document.createElement("style");
  109. styleEl.innerHTML = options.style;
  110. document.body.append(styleEl);
  111. }
  112. // 每个组件加载
  113. this.showComponentName = this.pages[Object.keys(this.pages)[0]]["childrens"][0]["componentName"];
  114. resolve(name, options);
  115. pageLoading.close();
  116. }, (err) => {
  117. pageLoading.close();
  118. reject(err);
  119. });
  120. });
  121. },
  122. filterData(data, keys = []) {
  123. let returnData = {};
  124. for (const key in data) {
  125. if (!keys.includes(key)) {
  126. returnData[key] = data[key];
  127. }
  128. }
  129. return returnData;
  130. },
  131. async save() {
  132. const submitData = {
  133. goods: {},
  134. widgets: {},
  135. };
  136. let extraSubmitData = {}
  137. let isPass = true;
  138. for (const key in this.pages) {
  139. const childrens = this.pages[key].childrens;
  140. for (const page of childrens) {
  141. const component = this.$refs[page.componentName][0];
  142. if (!component.validate) {
  143. throw new Error(page.title + " 子组件必须有validate方法");
  144. }
  145. //* 执行页面组件的validate方法,如果返回false不会发送数据给后端,否则会整合页面组件传过来的数据一并发送给后端
  146. const data = await component.validate();
  147. if (data === false) {
  148. isPass = false;
  149. // 循环组件逐一跳转校验失败的页面
  150. this.currentShowPage = page.group;
  151. this.showComponentName = page.componentName;
  152. console.log(page.componentName);
  153. console.log("表单验证不通过"); //TODO 后续去掉console log
  154. break;
  155. }
  156. //* 如果页面的widget_key等于goods就是商品的主要数据,否则其他都是插件的数据,放进widget里
  157. if (page.widget_key == "goods") {
  158. for (const propertyKey in data) {
  159. submitData["goods"][propertyKey] = data[propertyKey];
  160. }
  161. } else if (submitData["widgets"][page.widget_key]) {
  162. for (const propertyKey in data) {
  163. submitData["widgets"][page.widget_key][propertyKey] = data[propertyKey];
  164. }
  165. } else {
  166. submitData["widgets"][page.widget_key] = data;
  167. }
  168. // 获取额外的数据
  169. if (component.extraDate) {
  170. // throw new Error(page.title + " 子组件必须有extraDate方法");
  171. // 额外数据设置
  172. const extraDate = await component.extraDate();
  173. if(extraDate){
  174. extraSubmitData = {...extraSubmitData,...extraDate}
  175. }
  176. }
  177. }
  178. if (isPass === false) break;
  179. }
  180. if (isPass === false) return;
  181. console.log(submitData,{...extraSubmitData,...submitData});
  182. console.log(SaveGoodsDataUrl,"表单验证通过"); //TODO 后续去掉console log
  183. if(this.saveStatus){
  184. this.saveGoodsData(SaveGoodsDataUrl,submitData)
  185. }
  186. },
  187. saveGoodsData(url,submitData){
  188. this.saveStatus = false
  189. this.$http.post(url, submitData).then(response => {
  190. console.log(response,'response');
  191. if (response.data.result) {
  192. this.$message({type: 'success',message: '成功!'});
  193. window.location.href = GoodsList;
  194. } else{
  195. console.log(response.data.msg);
  196. this.$message({type: 'error',message: response.data.msg});
  197. }
  198. this.saveStatus = true
  199. }),function(res){
  200. console.log(res);
  201. };
  202. },
  203. chooseTab(subPageItem) {
  204. this.showComponentName = subPageItem.componentName;
  205. },
  206. },
  207. computed: {
  208. subPages() {
  209. if (!this.currentShowPage) return [];
  210. return this.pages[this.currentShowPage]["childrens"] || [];
  211. },
  212. },
  213. watch: {
  214. currentShowPage() {
  215. if (this.subPages.length > 0) {
  216. this.showComponentName = this.subPages[0]["componentName"];
  217. }
  218. },
  219. },
  220. });