menu.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
  2. var Controller = {
  3. index: () => {
  4. const { reactive, onMounted } = Vue
  5. const index = {
  6. setup() {
  7. const state = reactive({
  8. current: [],
  9. data: [],
  10. order: '',
  11. sort: '',
  12. })
  13. function getData() {
  14. Fast.api.ajax({
  15. url: 'shopro/wechat/menu',
  16. type: 'GET',
  17. data: {
  18. page: pagination.page,
  19. list_rows: pagination.list_rows,
  20. order: state.order,
  21. sort: state.sort,
  22. },
  23. }, function (ret, res) {
  24. state.current = res.data.current
  25. state.data = res.data.list.data
  26. pagination.total = res.data.list.total
  27. return false
  28. }, function (ret, res) { })
  29. }
  30. function onChangeSort({ prop, order }) {
  31. state.order = order == 'ascending' ? 'asc' : 'desc';
  32. state.sort = prop;
  33. getData();
  34. }
  35. const pagination = reactive({
  36. page: 1,
  37. list_rows: 10,
  38. total: 0,
  39. })
  40. function onAdd() {
  41. Fast.api.open(`shopro/wechat/menu/add?type=add`, "添加", {
  42. callback() {
  43. getData()
  44. }
  45. })
  46. }
  47. function onEdit(id) {
  48. Fast.api.open(`shopro/wechat/menu/edit?type=edit&id=${id}`, "编辑", {
  49. callback() {
  50. getData()
  51. }
  52. })
  53. }
  54. function onDelete(id) {
  55. Fast.api.ajax({
  56. url: `shopro/wechat/menu/delete/id/${id}`,
  57. type: 'DELETE',
  58. }, function (ret, res) {
  59. getData()
  60. }, function (ret, res) { })
  61. }
  62. function onPublish(id) {
  63. Fast.api.ajax({
  64. url: `shopro/wechat/menu/publish/id/${id}`,
  65. type: 'POST',
  66. }, function (ret, res) {
  67. getData()
  68. }, function (ret, res) { })
  69. }
  70. function onCopy(id) {
  71. Fast.api.ajax({
  72. url: `shopro/wechat/menu/copy/id/${id}`,
  73. type: 'POST',
  74. }, function (ret, res) {
  75. getData()
  76. }, function (ret, res) { })
  77. }
  78. onMounted(() => {
  79. getData()
  80. })
  81. return {
  82. state,
  83. getData,
  84. onChangeSort,
  85. pagination,
  86. onAdd,
  87. onEdit,
  88. onDelete,
  89. onPublish,
  90. onCopy,
  91. }
  92. }
  93. }
  94. createApp('index', index);
  95. },
  96. add: () => {
  97. Controller.form();
  98. },
  99. edit: () => {
  100. Controller.form();
  101. },
  102. form: () => {
  103. const { reactive, ref, onMounted, getCurrentInstance } = Vue
  104. const addEdit = {
  105. setup() {
  106. const { proxy } = getCurrentInstance();
  107. const state = reactive({
  108. type: new URLSearchParams(location.search).get('type'),
  109. id: new URLSearchParams(location.search).get('id'),
  110. rightShow: false,
  111. selectLevel: null,
  112. selectedIndex1: null,
  113. selectedIndex2: null,
  114. right: [],
  115. })
  116. const defaultSubButton = {
  117. name: '未命名',
  118. type: 'view',
  119. selected: true,
  120. show: true,
  121. url: '',
  122. appid: '',
  123. pagepath: '',
  124. sub_button: [],
  125. media_type: 'news',
  126. media_id: '',
  127. };
  128. const form = reactive({
  129. model: {
  130. name: '',
  131. rules: []
  132. },
  133. rules: {
  134. name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  135. },
  136. })
  137. function getDetail() {
  138. Fast.api.ajax({
  139. url: `shopro/wechat/menu/detail/id/${state.id}`,
  140. type: 'GET',
  141. }, function (ret, res) {
  142. form.model = res.data;
  143. initData();
  144. return false
  145. }, function (ret, res) { })
  146. }
  147. function initData() {
  148. form.model.rules.forEach((d) => {
  149. loopData(d);
  150. });
  151. function loopData(d) {
  152. for (var key in defaultSubButton) {
  153. if (!d[key]) {
  154. d[key] = JSON.parse(JSON.stringify(defaultSubButton))[key];
  155. }
  156. d.selected = false;
  157. d.show = false;
  158. }
  159. if (d.type == 'click') {
  160. d.media_type = d.key?.split('|')[0];
  161. d.media_id = d.key?.split('|')[1];
  162. }
  163. if (d.sub_button && d.sub_button.length > 0) {
  164. d.sub_button.forEach((s) => {
  165. loopData(s);
  166. });
  167. }
  168. }
  169. }
  170. function onAddMenu(index, level) {
  171. //右侧显示
  172. state.rightShow = true;
  173. state.selectLevel = level;
  174. // 添加level2的数据
  175. if (index != null) {
  176. state.selectedIndex1 = index;
  177. form.model.rules.forEach((i) => {
  178. i.selected = false;
  179. if (i.sub_button) {
  180. i.sub_button.forEach((j) => {
  181. j.selected = false;
  182. });
  183. }
  184. });
  185. form.model.rules[index].sub_button.push(JSON.parse(JSON.stringify(defaultSubButton)));
  186. state.right = form.model.rules[index].sub_button[form.model.rules[index].sub_button.length - 1];
  187. state.selectedIndex2 = form.model.rules[index].sub_button.length - 1;
  188. } else {
  189. // 添加level1的数据 所有的level1不显示
  190. form.model.rules.forEach((i) => {
  191. i.selected = false;
  192. i.show = false;
  193. });
  194. form.model.rules.push(JSON.parse(JSON.stringify(defaultSubButton)));
  195. state.selectedIndex1 = form.model.rules.length - 1;
  196. state.right = form.model.rules[form.model.rules.length - 1];
  197. }
  198. }
  199. function onEditMenu(index1, index2) {
  200. state.selectedIndex1 = index1;
  201. state.selectedIndex2 = index2;
  202. state.rightShow = true;
  203. form.model.rules.forEach((i) => {
  204. i.selected = false;
  205. i.show = false;
  206. if (i.sub_button) {
  207. i.sub_button.forEach((j) => {
  208. j.selected = false;
  209. });
  210. }
  211. });
  212. form.model.rules[index1].show = true;
  213. if (index2 == null) {
  214. state.selectLevel = 1;
  215. form.model.rules[index1].selected = true;
  216. form.model.rules[index1].show = true;
  217. state.right = form.model.rules[index1];
  218. } else {
  219. state.selectLevel = 2;
  220. form.model.rules[index1].sub_button[index2].selected = true;
  221. state.right = form.model.rules[index1].sub_button[index2];
  222. }
  223. getMaterialSelect()
  224. }
  225. function onDeleteMenu() {
  226. if (state.selectedIndex2 != null) {
  227. form.model.rules[state.selectedIndex1].sub_button.splice(state.selectedIndex2, 1);
  228. if (form.model.rules[state.selectedIndex1].sub_button.length > 0) {
  229. if (state.selectedIndex2 == 0) {
  230. form.model.rules[state.selectedIndex1].sub_button[0].selected = true;
  231. state.right = menuData[state.selectedIndex1].sub_button[0];
  232. } else {
  233. form.model.rules[state.selectedIndex1].sub_button[state.selectedIndex2 - 1].selected = true;
  234. state.right = form.model.rules[state.selectedIndex1].sub_button[state.selectedIndex2 - 1];
  235. state.selectedIndex2--;
  236. }
  237. } else {
  238. state.right = {};
  239. state.rightShow = false;
  240. }
  241. } else {
  242. form.model.rules.splice(state.selectedIndex1, 1);
  243. if (form.model.rules.length > 0) {
  244. if (state.selectedIndex1 == 0) {
  245. form.model.rules[0].selected = true;
  246. form.model.rules[0].show = true;
  247. state.right = form.model.rules[0];
  248. } else {
  249. form.model.rules[state.selectedIndex1 - 1].selected = true;
  250. form.model.rules[state.selectedIndex1 - 1].show = true;
  251. state.right = form.model.rules[state.selectedIndex1 - 1];
  252. state.selectedIndex1--;
  253. }
  254. } else {
  255. state.right = {};
  256. state.rightShow = false;
  257. }
  258. }
  259. }
  260. function onSelectUrl() {
  261. Fast.api.open("shopro/data/page/select", "选择链接", {
  262. callback(data) {
  263. state.right.url = data.fullPath.url;
  264. if (state.right.type == 'miniprogram') {
  265. state.right.appid = data.fullPath.appid;
  266. state.right.pagepath = data.fullPath.pagepath;
  267. }
  268. }
  269. })
  270. }
  271. function onChangeType() {
  272. if (state.right.type == 'click') {
  273. getMaterialSelect();
  274. }
  275. }
  276. function onChangeMediaType() {
  277. material.pagination.page = 1
  278. getMaterialSelect()
  279. }
  280. const material = reactive({
  281. select: [],
  282. pagination: {
  283. page: 1,
  284. list_rows: 10,
  285. total: 0,
  286. }
  287. })
  288. function getMaterialSelect() {
  289. Fast.api.ajax({
  290. url: 'shopro/wechat/material/select',
  291. type: 'GET',
  292. data: {
  293. type: state.right.media_type,
  294. page: material.pagination.page,
  295. list_rows: material.pagination.list_rows,
  296. },
  297. }, function (ret, res) {
  298. material.select = initMaterialData(res.data.data, state.right.media_type)
  299. material.pagination.total = res.data.total
  300. return false
  301. }, function (ret, res) { })
  302. }
  303. function initMaterialData(data, type) {
  304. let options = [];
  305. if (type == 'news') {
  306. data.forEach((i) => {
  307. i.content.news_item.forEach((e) => {
  308. options.push({
  309. media_id: i.media_id,
  310. title: e.title,
  311. thumb_url: e.thumb_url,
  312. type,
  313. });
  314. });
  315. });
  316. } else if (type == 'image') {
  317. data.forEach((i) => {
  318. options.push({
  319. media_id: i.media_id,
  320. title: i.name,
  321. thumb_url: i.url,
  322. type,
  323. });
  324. });
  325. } else if (type == 'video') {
  326. data.forEach((i) => {
  327. options.push({
  328. media_id: i.media_id,
  329. title: i.name,
  330. thumb_url: i.cover_url,
  331. type,
  332. });
  333. });
  334. } else if (type == 'voice') {
  335. data.forEach((i) => {
  336. options.push({
  337. media_id: i.media_id,
  338. title: i.name,
  339. thumb_url: '',
  340. type,
  341. });
  342. });
  343. } else if (type == 'text') {
  344. data.forEach((i) => {
  345. options.push({
  346. media_id: i.id,
  347. title: i.content,
  348. thumb_url: i.content,
  349. type,
  350. });
  351. });
  352. } else if (type == 'link') {
  353. data.forEach((i) => {
  354. options.push({
  355. media_id: i.id,
  356. title: i.content.title,
  357. thumb_url: i.content.image,
  358. description: i.content.description,
  359. type,
  360. });
  361. });
  362. }
  363. return options;
  364. }
  365. function formatData() {
  366. // 不同类型包含的数据组
  367. const view = ['name', 'type', 'url', 'sub_button'];
  368. const miniprogram = ['name', 'type', 'url', 'appid', 'pagepath', 'sub_button'];
  369. const click = ['name', 'type', 'media_type', 'media_id', 'sub_button'];
  370. const data = JSON.parse(JSON.stringify(form.model.rules));
  371. data.forEach((d) => {
  372. loopData(d);
  373. });
  374. function loopData(d) {
  375. if (d.type == 'view') {
  376. for (let j in d) {
  377. if (!view.includes(j)) delete d[j];
  378. }
  379. }
  380. if (d.type == 'miniprogram') {
  381. for (let j in d) {
  382. if (!miniprogram.includes(j)) delete d[j];
  383. }
  384. }
  385. if (d.type == 'click') {
  386. for (let j in d) {
  387. if (!click.includes(j)) delete d[j];
  388. }
  389. d.key = d.media_type + '|' + d.media_id;
  390. delete d.media_type;
  391. delete d.media_id;
  392. }
  393. if (d.sub_button && d.sub_button.length > 0) {
  394. for (let j in d) {
  395. if (j != 'name' && j != 'sub_button') delete d[j];
  396. }
  397. d.sub_button.forEach((s) => {
  398. loopData(s);
  399. });
  400. } else {
  401. delete d.sub_button;
  402. }
  403. }
  404. return data;
  405. }
  406. function onConfirm(data = {}) {
  407. let submitForm = { name: form.model.name, rules: formatData(), ...data };
  408. // proxy.$refs['formRef'].validate((valid) => {
  409. // if (valid) {
  410. Fast.api.ajax({
  411. url: state.type == 'add' ? 'shopro/wechat/menu/add' : `shopro/wechat/menu/edit/id/${state.id}`,
  412. type: 'POST',
  413. data: submitForm,
  414. }, function (ret, res) {
  415. Fast.api.close()
  416. }, function (ret, res) { })
  417. // }
  418. // });
  419. }
  420. function onPublish() {
  421. onConfirm({ publish: 1 })
  422. }
  423. onMounted(() => {
  424. state.type == 'edit' && getDetail()
  425. })
  426. return {
  427. state,
  428. form,
  429. onAddMenu,
  430. onEditMenu,
  431. onDeleteMenu,
  432. onSelectUrl,
  433. onChangeType,
  434. onChangeMediaType,
  435. material,
  436. getMaterialSelect,
  437. onConfirm,
  438. onPublish
  439. }
  440. }
  441. }
  442. createApp('addEdit', addEdit);
  443. }
  444. };
  445. return Controller;
  446. });