@infly/libs 2.0.26 → 2.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/bin/cli.js +29 -21
  2. package/build/build-dist/index.js +258 -61
  3. package/build/webpack5/remove-legacy-assets-plugin.js +84 -0
  4. package/build/webpack5/webpack.base.js +228 -20
  5. package/build/webpack5/webpack.base.test.js +59 -0
  6. package/index.js +10 -0
  7. package/module/Permission.js +121 -55
  8. package/module/REST.js +136 -26
  9. package/module/Router.js +15 -0
  10. package/module/Uts.js +380 -331
  11. package/module/cjs/deep-merge.cjs +38 -0
  12. package/module/cjs/page-config.cjs +119 -0
  13. package/module/cjs/request-url-rules.cjs +55 -0
  14. package/package.json +11 -10
  15. package/script/build/command.js +48 -0
  16. package/script/build/env.js +28 -0
  17. package/script/build/git.js +252 -0
  18. package/script/build/preview.js +75 -0
  19. package/script/build/webhook.js +118 -0
  20. package/script/git-automation/check-packages.js +11 -8
  21. package/script/git-automation/git-utils.js +67 -0
  22. package/script/git-automation/index.js +378 -106
  23. package/script/index.js +8 -8
  24. package/script/pts/cloud-scenes.mjs +65 -0
  25. package/script/pts/cloud.js +151 -0
  26. package/script/pts/generate-cloud-params.mjs +210 -0
  27. package/script/pts/generate-cloud-params.test.mjs +67 -0
  28. package/script/webhook/webhook.js +75 -4
  29. package/store/modules/user.js +111 -9
  30. package/tools/auto-export.js +56 -0
  31. package/tools/file-export.js +32 -9
  32. package/tools/file-process.js +3 -0
  33. package/tools/project-preview.js +110 -97
  34. package/dataInit/commonTypeMap.js +0 -31
  35. package/dataInit/marketingActivitiesMap.js +0 -214
  36. package/dataInit/orderMap.js +0 -13
  37. package/dataInit/personalMap.js +0 -19
  38. package/dataInit/settlementMap.js +0 -17
  39. package/types/unused.index.d.ts +0 -71
@@ -6,7 +6,7 @@ const CONFIG = {
6
6
  settings: {},
7
7
  login: () => Promise.resolve(),
8
8
  getInfo: () => Promise.resolve(),
9
- resetRouter: () => {}
9
+ redirectRoute: {}
10
10
  };
11
11
 
12
12
  function init(config = {}) {
@@ -76,13 +76,22 @@ const userModule = {
76
76
  SET_CHAT_TOKEN: (state, token) => {
77
77
  state.chatToken = token;
78
78
  TokenService.setChatToken(token);
79
+ },
80
+ SET_PERMISSION_CODES: (state, codes) => {
81
+ state.permission_codes = codes || [];
82
+ Uts.storage.set(CONFIG.settings.permissionsCodeKey, codes);
83
+ },
84
+ UPDATE_ROUTES: (state, menus_permission_codes) => {
85
+ const constantRoutes = CONFIG?.router?.options?.routes || [];
86
+ updateRoutesPermission(constantRoutes, menus_permission_codes);
87
+ CONFIG?.router?.resetRouter?.(constantRoutes);
79
88
  }
80
89
  },
81
90
  actions: {
82
91
  login({ commit }, userInfo) {
83
92
  const { mobile, sms_code } = userInfo;
84
93
  return new Promise((resolve, reject) => {
85
- CONFIG.login({
94
+ CONFIG?.login?.({
86
95
  mobile: mobile,
87
96
  sms_code: sms_code
88
97
  })
@@ -104,8 +113,18 @@ const userModule = {
104
113
  reject("验证失败,请重新登录。");
105
114
  }
106
115
 
107
- const { name, header, map_key, merchantinfo } = response;
116
+ const {
117
+ name,
118
+ header,
119
+ map_key,
120
+ merchantinfo,
121
+ permission_codes = [],
122
+ menus,
123
+ menus_permission_codes = Uts.pluck(menus, "path") || []
124
+ } = response;
108
125
  const { service_token } = merchantinfo || {};
126
+ const fullePermissionCodes = [...permission_codes, ...menus_permission_codes];
127
+
109
128
  commit("SET_USER", response);
110
129
  commit("SET_NAME", name);
111
130
  commit("SET_AVATAR", header);
@@ -115,7 +134,15 @@ const userModule = {
115
134
  commit("SET_CHAT_TOKEN", service_token);
116
135
  }
117
136
 
118
- resolve(response);
137
+ if (
138
+ CONFIG.settings.permissionsCodeKey &&
139
+ JSON.stringify(fullePermissionCodes) !==
140
+ JSON.stringify(Uts.storage.get(CONFIG.settings.permissionsCodeKey))
141
+ ) {
142
+ commit("SET_PERMISSION_CODES", fullePermissionCodes);
143
+ }
144
+ commit("UPDATE_ROUTES", menus_permission_codes);
145
+ resolve({ ...response, PMRedirectPath: CONFIG.redirectRoute.redirect });
119
146
  })
120
147
  .catch((error) => {
121
148
  reject(error);
@@ -123,16 +150,16 @@ const userModule = {
123
150
  });
124
151
  },
125
152
 
126
- logout({ commit, state }) {
153
+ logout({ commit, state }, payload) {
127
154
  return new Promise((resolve, reject) => {
128
155
  TokenService.removeAllTokens();
129
156
  commit("RESET_STATE");
130
157
  commit("SET_MAPKEY", "");
158
+ commit("SET_CHAT_TOKEN", "");
159
+ commit("SET_PERMISSION_CODES", "");
131
160
 
132
- if (CONFIG.router) {
133
- Uts.isFunction(CONFIG.router.push) && CONFIG.router.push("/login");
134
- Uts.isFunction(CONFIG.router.resetRouter) &&
135
- CONFIG.router.resetRouter();
161
+ if (payload?.redirectLogin) {
162
+ CONFIG?.router?.push?.("/login");
136
163
  }
137
164
 
138
165
  if (TokenService.getUrlToken()) {
@@ -160,6 +187,81 @@ const userModule = {
160
187
  }
161
188
  };
162
189
 
190
+ // 递归更新路由权限
191
+ // 递归应用路由权限(设置 hidden)
192
+ const applyRoutesPermission = (routes = []) => {
193
+ routes.forEach((route) => {
194
+ if (route.meta?.permission && !route.hidden) {
195
+ route.hidden = !Uts.getPM(route.meta.permission);
196
+ }
197
+ if (route.children?.length) {
198
+ applyRoutesPermission(route.children);
199
+ }
200
+ });
201
+ };
202
+
203
+ // 深度优先查找第一个可访问的叶子路由完整路径
204
+ const getFirstAccessiblePath = (routes = [], parentPath = "") => {
205
+ for (const route of routes) {
206
+ if (route.hidden || !route.path) continue;
207
+
208
+ // 绝对路径直接用,相对路径拼接父路径
209
+ const fullPath = route.path.startsWith("/")
210
+ ? route.path
211
+ : parentPath
212
+ ? `${parentPath}/${route.path}`
213
+ : route.path;
214
+
215
+ if (route.children?.length) {
216
+ const childPath = getFirstAccessiblePath(route.children, fullPath);
217
+ if (childPath) return childPath;
218
+ } else {
219
+ return fullPath;
220
+ }
221
+ }
222
+ return "";
223
+ };
224
+
225
+ // 更新路由权限并设置重定向
226
+ const findAccessibleRouteByPath = (routes = [], targetPath, parentPath = "") => {
227
+ if (!targetPath) return null;
228
+
229
+ for (const route of routes) {
230
+ if (route.hidden || !route.path) continue;
231
+
232
+ const fullPath = route.path.startsWith("/")
233
+ ? route.path
234
+ : parentPath
235
+ ? `${parentPath}/${route.path}`
236
+ : route.path;
237
+
238
+ if (fullPath === targetPath) {
239
+ return route;
240
+ }
241
+
242
+ if (route.children?.length) {
243
+ const matched = findAccessibleRouteByPath(route.children, targetPath, fullPath);
244
+ if (matched) return matched;
245
+ }
246
+ }
247
+
248
+ return null;
249
+ };
250
+
251
+ const updateRoutesPermission = (routes = []) => {
252
+ applyRoutesPermission(routes);
253
+
254
+ const redirectRoute = routes.find((r) => r.path === "");
255
+ if (redirectRoute) {
256
+ const availableRoutes = routes.filter((r) => r.path !== "");
257
+ const initRoutePath = CONFIG.settings?.projectConfig?.initRoutePath;
258
+ const initRoute = findAccessibleRouteByPath(availableRoutes, initRoutePath);
259
+ const firstPath = getFirstAccessiblePath(availableRoutes);
260
+ redirectRoute.redirect = initRoute ? initRoutePath : firstPath || "*";
261
+ CONFIG.redirectRoute = redirectRoute;
262
+ }
263
+ };
264
+
163
265
  export default {
164
266
  ...userModule,
165
267
  init
@@ -0,0 +1,56 @@
1
+ /**
2
+ * 自动导出目录下所有文件
3
+ * @param {Function} requireContext - require.context 返回的函数
4
+ * @param {RegExp} [filePattern=/\.vue$/] - 文件匹配正则
5
+ * @returns {Object} 导出对象,key 为文件名(不含扩展名),value 为模块内容
6
+ *
7
+ * @example
8
+ * // 在 components/Dialog/index.js 中使用
9
+ * import { autoExportFiles } from '@infly/libs/tools/auto-export.js';
10
+ * const components = autoExportFiles(require.context('./', false, /\.vue$/));
11
+ * Object.keys(components).forEach(name => {
12
+ * module.exports[name] = components[name];
13
+ * });
14
+ *
15
+ * // 或者直接一行
16
+ * Object.assign(module.exports, autoExportFiles(require.context('./', false, /\.vue$/)));
17
+ */
18
+ function autoExportFiles(requireContext, filePattern = /\.vue$/) {
19
+ if (!requireContext || typeof requireContext !== 'function') {
20
+ console.error('autoExportFiles: requireContext 必须是 require.context 返回的函数');
21
+ return {};
22
+ }
23
+
24
+ const exports = {};
25
+
26
+ requireContext.keys().forEach(fileName => {
27
+ // 跳过 index 文件自身
28
+ if (fileName.includes('index')) return;
29
+
30
+ const componentConfig = requireContext(fileName);
31
+ const componentName = fileName
32
+ .replace(/^\.\//, '') // 移除 './'
33
+ .replace(/\.\w+$/, ''); // 移除扩展名
34
+
35
+ exports[componentName] = componentConfig.default || componentConfig;
36
+ });
37
+
38
+ return exports;
39
+ }
40
+
41
+ /**
42
+ * 简化版:直接挂载到 module.exports
43
+ * @param {Function} requireContext - require.context 返回的函数
44
+ * @param {Object} targetExports - 目标导出对象(通常是 module.exports)
45
+ *
46
+ * @example
47
+ * // 在 components/Dialog/index.js 中使用
48
+ * import { autoExportToModule } from '@infly/libs/tools/auto-export.js';
49
+ * autoExportToModule(require.context('./', false, /\.vue$/), module.exports);
50
+ */
51
+ function autoExportToModule(requireContext, targetExports) {
52
+ const files = autoExportFiles(requireContext);
53
+ Object.assign(targetExports, files);
54
+ }
55
+
56
+ export { autoExportFiles, autoExportToModule };
@@ -22,7 +22,9 @@ async function exportFile(config) {
22
22
  reqMethod = "get",
23
23
  Message = {},
24
24
  MessageBox = {},
25
- Loading = {}
25
+ Loading = {},
26
+ hideConfirm = false,
27
+ confirmConfig = { message: "导出筛选后的所有文件, 是否继续?" }
26
28
  } = config || {};
27
29
 
28
30
  if (!url || !request) {
@@ -76,8 +78,8 @@ async function exportFile(config) {
76
78
 
77
79
  try {
78
80
  // 2. 确认框
79
- if (MessageBox && Uts.isFunction(MessageBox.confirm)) {
80
- await MessageBox.confirm("导出筛选后的所有文件, 是否继续?", "提示", {
81
+ if (MessageBox && Uts.isFunction(MessageBox.confirm) && !hideConfirm) {
82
+ await MessageBox.confirm(confirmConfig?.message, "提示", {
81
83
  confirmButtonText: "确定",
82
84
  cancelButtonText: "取消",
83
85
  type: "warning"
@@ -103,6 +105,11 @@ async function exportFile(config) {
103
105
  showMessage("error", "导出失败:不支持的请求方法!");
104
106
  return;
105
107
  }
108
+ const { code, message } = res || {};
109
+ if (code && (code != 0 || code != 200)) {
110
+ showMessage("error", message || "导出失败!");
111
+ return;
112
+ }
106
113
 
107
114
  const blob = new Blob([res], { type: "application/octet-stream" });
108
115
  const fullFileName = `${fileName}_${new Date().toISOString().slice(0, 10)}${suffix}`;
@@ -111,17 +118,17 @@ async function exportFile(config) {
111
118
  showMessage("success", "文件导出成功!");
112
119
  } catch (err) {
113
120
  console.error("导出错误:", err);
114
- const { response } = err || {};
115
- const { status, statusText } = response || {};
121
+ const { response, message: errMsg } = err || {};
122
+ const { status, statusText, message = errMsg } = response || {};
116
123
 
117
124
  if (status === 403 || statusText === "Forbidden") {
118
125
  showMessage("error", "无操作权限!");
119
126
  } else if (status === 404) {
120
127
  showMessage("error", "导出地址未找到!");
121
- } else if (err.message && err.message.includes("timeout")) {
128
+ } else if (message && message.includes("timeout")) {
122
129
  showMessage("error", "导出超时,请稍后再试!");
123
130
  } else {
124
- showMessage("error", "导出异常,请稍后再试!");
131
+ showMessage("error", message || "导出异常,请稍后再试!");
125
132
  }
126
133
  } finally {
127
134
  hideLoading(); // 隐藏加载
@@ -137,6 +144,22 @@ async function exportFile(config) {
137
144
  }
138
145
  }
139
146
 
140
- export {
141
- exportFile
147
+ // 创建 Vue mixin 对象
148
+ const fileExportMixin = {
149
+ methods: {
150
+ async $exportFile(config) {
151
+ // 自动注入 ElementUI 组件
152
+ const enhancedConfig = {
153
+ ...config,
154
+ Message: this.$message || Message,
155
+ MessageBox: this.$msgbox || MessageBox,
156
+ Loading: this.$loading || Loading,
157
+ request: config.request || this.$axios
158
+ };
159
+
160
+ return await exportFile(enhancedConfig);
161
+ }
162
+ }
142
163
  };
164
+
165
+ export { exportFile, fileExportMixin };
@@ -12,6 +12,9 @@ function scriptWrite(filePath, scriptsList, updateKey = "scripts") {
12
12
  pkg[updateKey] = pkg[updateKey] || {};
13
13
  if (Array.isArray(scriptsList)) {
14
14
  scriptsList.forEach(item => {
15
+ if (pkg[updateKey][item.key]) {
16
+ pkg[updateKey][`origin:${item.key}`] = pkg[updateKey][item.key];
17
+ }
15
18
  pkg[updateKey][item.key] = item.value;
16
19
  });
17
20
  } else if (typeof scriptsList === "object") {
@@ -10,126 +10,139 @@ const projectRoot = process.cwd().replace(/\\node_modules.*$/g, "");
10
10
  const projectPkgPath = path.resolve(projectRoot, "package.json");
11
11
  const projectVueConfigPath = path.resolve(projectRoot, "vue.config.js");
12
12
  const projectConfig = fs.existsSync(projectVueConfigPath) ? require(projectVueConfigPath) : {};
13
+ const projectPackage = fs.existsSync(projectPkgPath) ? require(projectPkgPath) : {};
13
14
  const rawArgv = process.argv.slice(2);
14
15
  const args = rawArgv.join(" ");
15
16
 
17
+ function getBuildContext() {
18
+ try {
19
+ return JSON.parse(process.env.INFLY_BUILD_CONTEXT || "{}");
20
+ } catch {
21
+ return {};
22
+ }
23
+ }
24
+
25
+ const buildContext = getBuildContext();
26
+
27
+ global.logColor = global.logColor || {
28
+ success: "\n\x1b[32m%s\x1b[0m",
29
+ error: "\n\x1b[31m%s\x1b[0m",
30
+ warning: "\n\x1b[33m%s\x1b[0m",
31
+ link: "\x1b[34m%s\x1b[0m",
32
+ info: "\n\x1b[36m%s\x1b[0m"
33
+ };
34
+
16
35
  const DEFAULT_CONFIG = {
17
- port: 9001,
18
- publicPath: "/",
19
- outputDir: "dist"
36
+ port: 9001,
37
+ publicPath: "/",
38
+ outputDir: "dist"
20
39
  };
21
40
 
22
41
  function scriptInit() {
23
- if (fs.existsSync(projectVueConfigPath)) {
24
- return;
25
- }
26
- scriptWrite(projectPkgPath, previewList);
42
+ if (fs.existsSync(projectVueConfigPath)) {
43
+ return;
44
+ }
45
+ scriptWrite(projectPkgPath, previewList);
27
46
  }
28
47
 
29
- /**
30
- * 检查端口是否可用
31
- * @param {number} port - 端口号
32
- * @returns {Promise<boolean>} - 端口是否可用
33
- */
34
48
  function isPortAvailable(port) {
35
- return new Promise((resolve) => {
36
- const server = net.createServer();
37
-
38
- server.listen(port, () => {
39
- server.once('close', () => {
40
- resolve(true);
41
- });
42
- server.close();
43
- });
44
-
45
- server.on('error', () => {
46
- resolve(false);
47
- });
49
+ return new Promise((resolve) => {
50
+ const server = net.createServer();
51
+
52
+ server.listen(port, () => {
53
+ server.once("close", () => {
54
+ resolve(true);
55
+ });
56
+ server.close();
57
+ });
58
+
59
+ server.on("error", () => {
60
+ resolve(false);
48
61
  });
62
+ });
49
63
  }
50
64
 
51
- /**
52
- * 查找可用端口
53
- * @param {number} startPort - 起始端口
54
- * @param {number} maxTries - 最大尝试次数
55
- * @returns {Promise<number>} - 可用端口
56
- */
57
65
  async function findAvailablePort(startPort, maxTries = 10) {
58
- for (let i = 0; i < maxTries; i++) {
59
- const port = startPort + i;
60
- const available = await isPortAvailable(port);
61
-
62
- if (available) {
63
- if (i > 0) {
64
- console.log(global.logColor.warning, `⚠️ 端口 ${startPort} 被占用,使用端口 ${port}`);
65
- }
66
- return port;
67
- }
66
+ for (let i = 0; i < maxTries; i++) {
67
+ const port = startPort + i;
68
+ const available = await isPortAvailable(port);
69
+
70
+ if (available) {
71
+ if (i > 0) {
72
+ console.log(global.logColor.warning, `⚠️ 端口 ${startPort} 被占用,使用端口 ${port}`);
73
+ }
74
+ return port;
68
75
  }
69
-
70
- throw new Error(`无法找到可用端口,已尝试从 ${startPort} 到 ${startPort + maxTries - 1}`);
76
+ }
77
+
78
+ throw new Error(`无法找到可用端口,已尝试从 ${startPort} 到 ${startPort + maxTries - 1}`);
71
79
  }
72
80
 
73
81
  async function init(skipBuild = false) {
74
- try {
75
- const { connect } = require("../lib/server/connect");
76
- const { serveStatic } = require("../lib/server/serve-static");
77
- const app = connect();
78
- const noBuild = skipBuild || rawArgv.includes("--no-build");
79
- const { devServer } = projectConfig || {};
80
- const { port: devServerPort } = devServer || {};
81
- projectConfig.port = devServerPort || DEFAULT_CONFIG.port;
82
- const { publicPath, outputDir, port } = {
83
- ...DEFAULT_CONFIG,
84
- ...projectConfig
85
- };
86
- const baseListenPort = port - 1000;
87
-
88
- if (!noBuild) {
89
- buildProject();
90
- }
91
-
92
- // ✅ 查找可用端口
93
- const listenPort = await findAvailablePort(baseListenPort);
94
-
95
- app.use(
96
- publicPath,
97
- serveStatic(outputDir, {
98
- index: ["index.html", "/"]
99
- })
100
- );
101
-
102
- const server = app.listen(listenPort, function () {
103
- console.log(global.logColor.success, `\x1b[42m\x1b[30m DONE \x1b[0m\x1b[32m 项目构建预览,CTRL + C结束:`);
104
- console.log(global.logColor.link, `http://localhost:${listenPort}${publicPath}`);
105
- });
106
-
107
- // ✅ 处理服务器启动错误
108
- server.on('error', (error) => {
109
- if (error.code === 'EADDRINUSE') {
110
- console.log(global.logColor.error, `❌ 端口 ${listenPort} 仍然被占用`);
111
- } else {
112
- console.log(global.logColor.error, `❌ 服务器启动失败:${error.message}`);
113
- }
114
- });
115
-
116
- return server;
117
- } catch (error) {
118
- console.log(global.logColor.error, `❌ 预览项目失败:${error.message}`);
119
- throw error;
82
+ try {
83
+ const { connect } = require("../lib/server/connect");
84
+ const { serveStatic } = require("../lib/server/serve-static");
85
+ const app = connect();
86
+ const noBuild = skipBuild || rawArgv.includes("--no-build");
87
+ const { devServer } = projectConfig || {};
88
+ const { port: devServerPort } = devServer || {};
89
+ projectConfig.port = devServerPort || DEFAULT_CONFIG.port;
90
+ const { publicPath, outputDir, port } = {
91
+ ...DEFAULT_CONFIG,
92
+ ...projectConfig
93
+ };
94
+ const baseListenPort = port - 1000;
95
+
96
+ if (!noBuild) {
97
+ buildProject();
120
98
  }
99
+
100
+ const listenPort = await findAvailablePort(baseListenPort);
101
+
102
+ app.use(
103
+ publicPath,
104
+ serveStatic(outputDir, {
105
+ index: ["index.html", "/"]
106
+ })
107
+ );
108
+
109
+ const server = app.listen(listenPort, function () {
110
+ const previewUrl = `http://localhost:${listenPort}${publicPath}`;
111
+
112
+ if (buildContext.batchPreview === true || process.env.INFLY_BATCH_PREVIEW === "1") {
113
+ console.log(global.logColor.link, `${projectPackage.name || path.basename(projectRoot)}: ${previewUrl}`);
114
+ return;
115
+ }
116
+
117
+ console.log(global.logColor.success, `\x1b[42m\x1b[30m DONE \x1b[0m\x1b[32m 项目构建预览,CTRL + C结束:`);
118
+ console.log(global.logColor.link, previewUrl);
119
+ });
120
+
121
+ server.on("error", (error) => {
122
+ if (error.code === "EADDRINUSE") {
123
+ console.log(global.logColor.error, `❌ 端口 ${listenPort} 仍然被占用`);
124
+ } else {
125
+ console.log(global.logColor.error, `❌ 服务器启动失败:${error.message}`);
126
+ }
127
+ });
128
+
129
+ return server;
130
+ } catch (error) {
131
+ console.log(global.logColor.error, `❌ 预览项目失败:${error.message}`);
132
+ throw error;
133
+ }
121
134
  }
122
135
 
123
136
  function buildProject() {
124
- try {
125
- execSync(`vue-cli-service build ${args}`, { stdio: "inherit" });
126
- } catch (err) {
127
- console.error(global.logColor.error, "❌ 构建失败:", err.message);
128
- process.exit(1);
129
- }
137
+ try {
138
+ execSync(`vue-cli-service build ${args}`, { stdio: "inherit" });
139
+ } catch (err) {
140
+ console.error(global.logColor.error, "❌ 构建失败:", err.message);
141
+ process.exit(1);
142
+ }
130
143
  }
131
144
 
132
145
  module.exports = {
133
- init,
134
- scriptInit
146
+ init,
147
+ scriptInit
135
148
  };
@@ -1,31 +0,0 @@
1
- export default {
2
- roleList: [
3
- { name: "超级管理员", value: 1 },
4
- { name: "机构管理员", value: 2 },
5
- { name: "客户经理", value: 3 },
6
- { name: "其他员工", value: 4 }
7
- ],
8
- // 是否显示
9
- displayList: [{ name: "否", value: 2 }, { name: "是", value: 1 }],
10
- yesNoOptions: [{ name: "是", value: true }, { name: "否", value: false }],
11
- platformList: [
12
- { label: "邮惠权益后台(运营端)", name: "default" },
13
- { label: "邮惠权益后台(机构端)", name: "level" }
14
- ],
15
- miniProgramList: [
16
- { label: "邮乐享商圈", name: "xx_wx_wyh_shangquan", value: "xx_wx_wyh_shangquan" },
17
- { label: "微邮惠助手", name: "xx_fn_huili", value: "xx_fn_huili" },
18
- { label: "微邮惠商家", name: "xx_yf_merchant", value: "xx_yf_merchant" },
19
- { label: "邮惠权益", name: "xx_wx_yh_quanyi", value: "xx_wx_yh_quanyi" }
20
- ],
21
- weekDateOptions: [
22
- { name: "周一", value: 0 },
23
- { name: "周二", value: 1 },
24
- { name: "周三", value: 2 },
25
- { name: "周四", value: 3 },
26
- { name: "周五", value: 4 },
27
- { name: "周六", value: 5 },
28
- { name: "周日", value: 6 }
29
- ],
30
- dateTypeOptions: [{ name: "周期循环", value: 1 }, { name: "指定日期", value: 2 }]
31
- };