| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- # -*- coding: utf-8 -*-
- """
- Scan adminUI src/views and generate reverse-engineered menu structure document.
- """
- import os
- import re
- from collections import defaultdict
- from datetime import date
- ROOT = os.path.normpath(
- os.path.join(os.path.dirname(__file__), '..', '..', 'ylrz_saas_his_scrm_adminUI', 'src', 'views')
- )
- OUT = os.path.join(os.path.dirname(__file__), 'adminUI_views_menu_structure.md')
- SKIP_TOP = {'components', 'error', 'dashboard', 'icons', 'login', 'register', 'redirect'}
- SKIP_REL = re.compile(
- r'(components/|/profile/|authRole|authUser|selectUser|/data\.vue|/design\.vue|'
- r'/log\.vue|/editTable|/details\.vue|/my\.vue|sopLogsList|sopUserLogsSchedule|'
- r'/transferLog\.vue|/transfer\.vue|/darkRoom\.vue|/blackroom\.vue|config2\.vue|'
- r'/sopTempe/|mixins/)'
- )
- LIST_NAMES = {'index.vue', 'list.vue', 'myList.vue', 'order.vue', 'order1.vue'}
- ADMIN_ONLY_TOP = {
- 'admin', 'saas', 'sysUser', 'saler', 'shop', 'medical', 'food', 'todo',
- 'baidu', 'callRecord', 'aiSipCall', 'storeOrderOfflineItem', 'operation', 'hisStore',
- }
- TENANT_TOP = {
- 'qw': ('\u4f01\u5fae\u7ba1\u7406', 'qw'),
- 'wx': ('\u5fae\u4fe1\u7ba1\u7406', 'wx'),
- 'gw': ('\u5fae\u4fe1\u7ba1\u7406', 'wx'),
- 'crm': ('CRM\u5ba2\u6237', 'crm'),
- 'user': ('\u4f1a\u5458\u7ba1\u7406', 'member'),
- 'users': ('\u4f1a\u5458\u7ba1\u7406', 'member'),
- 'member': ('\u4f1a\u5458\u7ba1\u7406', 'member'),
- 'his': ('\u8bca\u6240\u7ba1\u7406', 'his'),
- 'store': ('\u5546\u57ce\u7ba1\u7406', 'store'),
- 'live': ('\u76f4\u64ad\u7ba1\u7406', 'live'),
- 'liveData': ('\u76f4\u64ad\u7ba1\u7406', 'live'),
- 'course': ('\u8bfe\u7a0b\u7ba1\u7406', 'course'),
- 'courseFinishTemp': ('\u8bfe\u7a0b\u7ba1\u7406', 'course'),
- 'fastGpt': ('AI\u804a\u5929', 'fastGpt'),
- 'FastGptExtUserTag': ('AI\u804a\u5929', 'fastGpt'),
- 'chat': ('AI\u804a\u5929', 'fastGpt'),
- 'aiob': ('AI\u804a\u5929', 'fastGpt'),
- 'lobster': ('\u9f99\u8679\u5f15\u64ce', 'lobster'),
- 'adv': ('\u5e7f\u544a\u6295\u653e', 'ad'),
- 'ad': ('\u5e7f\u544a\u6295\u653e', 'ad'),
- 'company': ('\u7cfb\u7edf\u7ba1\u7406', 'system'),
- 'system': ('\u7cfb\u7edf\u7ba1\u7406', 'system'),
- 'bill': ('\u8d22\u52a1\u7ba1\u7406', 'bill'),
- 'billing': ('\u8d22\u52a1\u7ba1\u7406', 'bill'),
- 'calendar': ('\u65e5\u7a0b\u7ba1\u7406', 'calendar'),
- 'statistics': ('\u6570\u636e\u7edf\u8ba1', 'statistics'),
- 'taskStatistics': ('\u6570\u636e\u7edf\u8ba1', 'statistics'),
- 'moduleUsage': ('\u6570\u636e\u7edf\u8ba1', 'statistics'),
- 'monitor': ('\u76d1\u63a7\u7ba1\u7406', 'watch'),
- 'watch': ('\u76d1\u63a7\u7ba1\u7406', 'watch'),
- 'tool': ('\u7cfb\u7edf\u5de5\u5177', 'system'),
- 'qwExternalContact': ('\u4f01\u5fae\u7ba1\u7406', 'qw'),
- }
- SECONDARY_HINTS = {
- 'qw': {
- 'msg': ['QwWorkTask', 'groupMsg', 'record', 'qwPushCount'],
- 'customer': ['externalContact', 'contactWay', 'drainageLink', 'assignRule', 'customerLink'],
- 'group': ['groupChat', 'groupLiveCode', 'groupActual'],
- 'moments': ['friendCircle', 'friendMaterial', 'friendWelcome'],
- 'drainage': ['appAdvertisingReport', 'appContactWay'],
- 'tag': ['tag', 'tagGroup', 'autoTags'],
- 'setting': ['qwDept', 'companyUser', 'material', 'welcome', 'applyIpad', 'userBehaviorData'],
- 'sop': ['sop', 'sopTemp', 'sopLogs', 'aiSop'],
- },
- 'store': {
- 'order': ['storeOrder', 'storeAfterSales', 'inquiryOrder', 'PromotionOrder', 'healthStoreOrder'],
- 'product': ['storeProduct', 'prescribe', 'shippingTemplates', 'package'],
- 'ops': ['storeShop', 'storeCoupon', 'homeArticle', 'exportTask', 'userPromoterApply', 'adv'],
- },
- 'his': {
- 'doctor': ['doctor', 'doctorBill', 'doctorExtract', 'doctorOperLog'],
- 'inquiry': ['inquiryOrder', 'inquiryOrderReport', 'patient'],
- 'store': ['storeOrder', 'storeProduct', 'storeBill'],
- 'content': ['article', 'articleCate', 'answer'],
- 'ai': ['aiWorkflow', 'aiDoctorRole', 'aiDoctorChatSession'],
- },
- 'system': {
- 'org': ['dept', 'post', 'user'],
- 'perm': ['role', 'menu'],
- 'config': ['dict', 'config', 'notice', 'keyword', 'set'],
- 'voice': ['companyVoiceDialog', 'companyVoiceRobotic'],
- },
- 'company': {
- 'org': ['companyDept', 'companyPost', 'companyUser'],
- 'perm': ['companyRole', 'companyMenu'],
- 'finance': ['companyRecharge', 'companyProfit', 'companyMoneyLogs', 'companyDeduct'],
- 'comm': ['companySms', 'companyVoice', 'companyWorkflow'],
- 'wx': ['wxAccount', 'wxUser', 'wxDialog'],
- },
- 'live': {
- 'ops': ['liveConsole', 'liveConfig', 'liveData', 'liveWatch'],
- 'order': ['liveOrder', 'liveAfterSales', 'healthLiveOrder'],
- 'interact': ['liveCoupon', 'liveQuestion', 'liveReward', 'comment'],
- },
- 'course': {
- 'content': ['videoResource', 'Material', 'period', 'courseFinishTemp'],
- 'study': ['userCourse', 'courseWatchLog', 'userWatch'],
- 'stat': ['statistics', 'courseUserStatistics', 'huaweiCloudStatistics'],
- },
- }
- GROUP_TITLES = {
- 'msg': '\u6d88\u606f\u7ba1\u7406', 'customer': '\u5ba2\u6237\u7ba1\u7406',
- 'group': '\u7fa4\u804a\u7ba1\u7406', 'moments': '\u670b\u53cb\u5708',
- 'drainage': '\u5f15\u6d41\u7ba1\u7406', 'tag': '\u6807\u7b7e\u7ba1\u7406',
- 'setting': '\u4f01\u5fae\u8bbe\u7f6e', 'sop': 'SOP/\u81ea\u52a8\u5316',
- 'order': '\u8ba2\u5355\u7ba1\u7406', 'product': '\u5546\u54c1\u7ba1\u7406',
- 'ops': '\u95e8\u5e97\u8fd0\u8425', 'doctor': '\u533b\u751f\u7ba1\u7406',
- 'inquiry': '\u95ee\u8bca\u7ba1\u7406', 'content': '\u5185\u5bb9\u7ba1\u7406',
- 'ai': 'AI/\u5de5\u4f5c\u6d41', 'org': '\u7ec4\u7ec7\u7ba1\u7406',
- 'perm': '\u6743\u9650\u7ba1\u7406', 'config': '\u7cfb\u7edf\u8bbe\u7f6e',
- 'voice': '\u8bed\u97f3/\u5916\u547c', 'finance': '\u8d22\u52a1',
- 'comm': '\u901a\u4fe1/\u5de5\u4f5c\u6d41', 'wx': '\u5fae\u4fe1\u8d26\u53f7',
- 'interact': '\u4e92\u52a8\u8425\u9500', 'study': '\u5b66\u4e60\u8ddf\u8e2a',
- 'stat': '\u7edf\u8ba1\u5206\u6790', 'general': '\u901a\u7528/\u5f85\u5206\u7ec4',
- }
- def to_component(rel_path):
- comp = rel_path.replace('\\', '/').replace('.vue', '')
- if comp.endswith('/index/index'):
- comp = comp[:-6]
- return comp
- def is_menu_page(rel_path, filename):
- if SKIP_REL.search(rel_path):
- return False
- parts = rel_path.replace('\\', '/').split('/')
- if parts[0] in SKIP_TOP:
- return False
- if filename in LIST_NAMES:
- return True
- if len(parts) == 2 and filename.endswith('.vue'):
- return True
- return False
- def scan_views():
- pages = []
- all_files = 0
- for dirpath, dirnames, filenames in os.walk(ROOT):
- dirnames[:] = [d for d in dirnames if d not in SKIP_TOP and d != 'mixins']
- for fn in filenames:
- if not fn.endswith('.vue'):
- continue
- all_files += 1
- full = os.path.join(dirpath, fn)
- rel = full[len(ROOT) + 1:]
- if is_menu_page(rel, fn):
- comp = to_component(rel)
- module = rel.replace('\\', '/').split('/')[1] if '/' in rel else fn.replace('.vue', '')
- pages.append({
- 'top': rel.replace('\\', '/').split('/')[0],
- 'module': module,
- 'component': comp,
- 'file': rel.replace('\\', '/'),
- })
- return pages, all_files
- def guess_secondary(top, module):
- hints = SECONDARY_HINTS.get(top, {})
- for group, keys in hints.items():
- for k in keys:
- if k.lower() in module.lower():
- return group
- return 'general'
- def build_markdown(pages, all_files):
- by_top = defaultdict(list)
- for p in pages:
- by_top[p['top']].append(p)
- agg_count = defaultdict(int)
- for p in pages:
- info = TENANT_TOP.get(p['top'])
- key = info[1] if info else ('other' if p['top'] in ADMIN_ONLY_TOP else 'other')
- agg_count[key] += 1
- L = []
- w = L.append
- w('# adminUI \u89c6\u56fe\u53cd\u5411\u68b3\u7406 \u2014 \u79df\u6237\u7ba1\u7406\u7aef\u83dc\u5355\u5efa\u8bae\u7ed3\u6784')
- w('')
- w('> \u6587\u6863\u7c7b\u578b\uff1a**\u53ea\u8bfb\u68b3\u7406**\uff0c\u6682\u4e0d\u4fee\u6539\u6570\u636e\u5e93\u6216\u4ee3\u7801\u3002')
- w('> \u626b\u63cf\u6765\u6e90\uff1a`ylrz_saas_his_scrm_adminUI/src/views`')
- w('> \u751f\u6210\u65e5\u671f\uff1a%s' % date.today().isoformat())
- w('> \u626b\u63cf\u7ed3\u679c\uff1a\u5171 **%d** \u4e2a `.vue` \u6587\u4ef6\uff0c\u8bc6\u522b **%d** \u4e2a\u53ef\u72ec\u7acb\u8def\u7531\u9875\u9762' % (all_files, len(pages)))
- w('')
- w('---')
- w('')
- w('## \u4e00\u3001\u68b3\u7406\u65b9\u6cd5')
- w('')
- w('| \u9879\u76ee | \u8bf4\u660e |')
- w('|------|------|')
- w('| \u9875\u9762\u8bc6\u522b | `index.vue` / `list.vue` / `myList.vue` \u53ca\u6a21\u5757\u6839\u76ee\u5f55\u5355\u5c42 `.vue` |')
- w('| \u6392\u9664 | `components/`\u3001\u8be6\u60c5\u9875\u3001\u6388\u6743\u9875\u3001\u5b57\u5178\u5b50\u9875\u3001\u8bbe\u8ba1\u5668\u3001\u65e5\u5fd7\u5b50\u9875\u7b49 |')
- w('| \u7ec4\u4ef6\u8def\u5ef6 | \u5bf9\u5e94\u540e\u7aef `sys_menu.component`\uff0c\u5982 `qw/externalContact/index` |')
- w('| \u8def\u7531\u52a0\u8f7d | \u540e\u7aef `getRouters` \u2192 `loadView(@/views/${component})` |')
- w('| \u53c2\u8003 | `src/views/admin/menu.js` \uff08\u603b\u540e\u53f0 `/admin/*` \u5bf9\u7167\u8868\uff09 |')
- w('')
- w('---')
- w('')
- w('## \u4e8c\u3001\u5efa\u8bae\u9876\u7ea7\u6a21\u5757\uff08\u79df\u6237 saasadminui \u9876\u680f\uff09')
- w('')
- w('| \u5e8f\u53f7 | \u6a21\u5757\u540d | path | \u89c6\u56fe\u6839\u76ee\u5f55 | \u9875\u9762\u6570 | \u5907\u6ce8 |')
- w('|------|--------|------|------------|--------|------|')
- tops = [
- (1, '\u9996\u9875', 'index', 'index.vue', 1, '\u4eea\u8868\u76d8\uff0c\u53ef hidden'),
- (2, '\u4f01\u5fae\u7ba1\u7406', 'qw', 'qw/', agg_count['qw'], ''),
- (3, '\u5fae\u4fe1\u7ba1\u7406', 'wx', 'wx/, gw/', agg_count['wx'], ''),
- (4, 'CRM\u5ba2\u6237', 'crm', 'crm/', agg_count['crm'], ''),
- (5, '\u4f1a\u5458\u7ba1\u7406', 'member', 'user/, users/, member/', agg_count['member'], ''),
- (6, '\u8bca\u6240\u7ba1\u7406', 'his', 'his/', agg_count['his'], ''),
- (7, '\u5546\u57ce\u7ba1\u7406', 'store', 'store/', agg_count['store'], 'canonical'),
- (8, '\u76f4\u64ad\u7ba1\u7406', 'live', 'live/, liveData/', agg_count['live'], ''),
- (9, '\u8bfe\u7a0b\u7ba1\u7406', 'course', 'course/, courseFinishTemp/', agg_count['course'], ''),
- (10, 'AI\u804a\u5929', 'fastGpt', 'fastGpt/, chat/, aiob/', agg_count['fastGpt'], ''),
- (11, '\u9f99\u8679\u5f15\u64ce', 'lobster', 'lobster/', agg_count['lobster'], ''),
- (12, '\u5e7f\u544a\u6295\u653e', 'ad', 'adv/, ad/', agg_count['ad'], ''),
- (13, '\u7cfb\u7edf\u7ba1\u7406', 'system', 'system/, company/', agg_count['system'], ''),
- (14, '\u8d22\u52a1\u7ba1\u7406', 'bill', 'bill/, billing/', agg_count['bill'], ''),
- (15, '\u65e5\u7a0b\u7ba1\u7406', 'calendar', 'calendar/', agg_count['calendar'], ''),
- (16, '\u6570\u636e\u7edf\u8ba1', 'statistics', 'statistics/, taskStatistics/', agg_count['statistics'], ''),
- (17, '\u76d1\u63a7\u7ba1\u7406', 'watch', 'watch/, monitor/', agg_count['watch'], ''),
- (18, '\u5176\u4ed6', 'other', '\u5e73\u53f0/\u9057\u7559', 0, '\u4e0d\u4e0b\u53d1\u79df\u6237\u9ed8\u8ba4\u83dc\u5355'),
- ]
- for row in tops:
- w('| %d | %s | `%s` | %s | %d | %s |' % row)
- w('')
- w('---')
- w('')
- w('## \u4e09\u3001\u603b\u540e\u53f0\u4e13\u7528\uff08\u5f52\u5165\u300c\u5176\u4ed6\u300d\uff09')
- w('')
- w('| \u76ee\u5f55 | \u9875\u9762\u6570 | \u8bf4\u660e |')
- w('|------|--------|------|')
- notes = {
- 'admin': '\u603b\u540e\u53f0\u4e1a\u52a1\uff08\u79df\u6237/\u4ee3\u7406/\u5916\u547c/\u77ed\u4fe1/\u8d22\u52a1\u5ba1\u8ba1\uff09',
- 'saas': 'SaaS \u8ba1\u8d39/\u79df\u6237\u5b57\u5178/\u79df\u6237\u83dc\u5355\u6a21\u677f',
- 'sysUser': '\u603b\u540e\u53f0\u5458\u5de5\uff08\u4e0e system/user \u4e0d\u540c\uff09',
- 'hisStore': '\u65e7\u7248\u5546\u57ce\uff0c\u4e0e store \u91cd\u590d',
- 'shop': '\u95e8\u5e97\u72ec\u7acb\u83dc\u5355\uff08\u9057\u7559\uff09',
- }
- for t in sorted(set(ADMIN_ONLY_TOP) | {'admin', 'saas'}):
- cnt = len(by_top.get(t, []))
- if cnt:
- w('| `%s/` | %d | %s |' % (t, cnt, notes.get(t, '\u5e73\u53f0\u6216\u9057\u7559')))
- w('')
- w('### 3.1 admin/menu.js \u5bf9\u7167\uff08\u603b\u540e\u53f0 /admin/*\uff09')
- w('')
- w('| \u83dc\u5355\u6807\u9898 | path | component |')
- w('|----------|------|-----------|')
- admin_rows = [
- ('\u6570\u636e\u770b\u677f', 'dashboard', 'admin/dashboard/index'),
- ('\u79df\u6237\u7ba1\u7406', 'company', 'admin/sysCompany/index'),
- ('\u79df\u6237\u6a21\u5757\u4f7f\u7528\u7edf\u8ba1', 'moduleUsage', 'admin/moduleUsage/index'),
- ('\u79df\u6237\u7ba1\u7406\u7aef\u83dc\u5355', 'tenantMenu', 'admin/tenantMenu/index'),
- ('\u79df\u6237\u9500\u552e\u7aef\u83dc\u5355', 'tenantCompany', 'admin/tenantCompany/index'),
- ('\u4ee3\u7406\u7ba1\u7406', 'proxy', 'admin/proxy/index'),
- ('\u6536\u8d39\u914d\u7f6e', 'serviceCost', 'admin/serviceCost/index'),
- ('\u5458\u5de5\u7ba1\u7406', 'sysUser', 'admin/sysUser/index'),
- ('\u89d2\u8272\u7ba1\u7406', 'role', 'system/role/index'),
- ('\u83dc\u5355\u7ba1\u7406', 'menu', 'system/menu/index'),
- ('\u5916\u547c\u7ba1\u7406', 'voice', 'admin/voice/index'),
- ('\u77ed\u4fe1\u7ba1\u7406', 'sms', 'admin/sms/index'),
- ('AI\u6a21\u578b\u914d\u7f6e', 'aiModel', 'admin/aiModel/index'),
- ('AI\u751f\u6210\u5de5\u4f5c\u6d41', 'workflowGenerate', 'lobster/workflow-generate/index'),
- ]
- for title, path, comp in admin_rows:
- w('| %s | `/admin/%s` | `%s` |' % (title, path, comp))
- w('')
- w('---')
- w('')
- w('## \u56db\u3001\u5404\u4e1a\u52a1\u6a21\u5757\u4e8c\u7ea7\u5206\u7ec4\u4e0e\u9875\u9762\u6e05\u5355')
- w('')
- detail = [
- ('qw', '\u4f01\u5fae\u7ba1\u7406', 'qw'),
- ('crm', 'CRM', 'crm'),
- ('store', '\u5546\u57ce', 'store'),
- ('his', '\u8bca\u6240', 'his'),
- ('live', '\u76f4\u64ad', 'live'),
- ('course', '\u8bfe\u7a0b', 'course'),
- ('fastGpt', 'AI', 'fastGpt'),
- ('company', '\u4f01\u4e1a/\u7ec4\u7ec7', 'company'),
- ('system', '\u7cfb\u7edf', 'system'),
- ('lobster', '\u9f99\u8679', 'lobster'),
- ('adv', '\u5e7f\u544a', 'ad'),
- ('wx', '\u5fae\u4fe1', 'wx'),
- ('monitor', '\u76d1\u63a7', 'monitor'),
- ]
- sec_no = 1
- for top_key, title, path_prefix in detail:
- items = list(by_top.get(top_key, []))
- if top_key == 'fastGpt':
- for extra in ('chat', 'aiob', 'FastGptExtUserTag'):
- items.extend(by_top.get(extra, []))
- if not items:
- continue
- w('### 4.%d %s (`%s/`) \u2014 %d \u9875' % (sec_no, title, top_key, len(items)))
- sec_no += 1
- w('')
- w('\u5efa\u8bae\u8def\u7531\u524d\u7f00\uff1a`/%s`' % path_prefix)
- w('')
- groups = defaultdict(list)
- for p in sorted(items, key=lambda x: x['component']):
- groups[guess_secondary(top_key, p['module'])].append(p)
- order = list(SECONDARY_HINTS.get(top_key, {}).keys()) + ['general']
- for g in order:
- if g not in groups:
- continue
- w('#### %s' % GROUP_TITLES.get(g, g))
- w('')
- w('| \u5efa\u8bae menu_name | component | \u6e90\u6587\u4ef6 |')
- w('|--------------|-----------|--------|')
- for p in groups[g]:
- w('| %s | `%s` | `%s` |' % (p['module'], p['component'], p['file']))
- w('')
- w('---')
- w('')
- w('## \u4e94\u3001\u91cd\u590d/\u9057\u7559\u6a21\u5757\u5408\u5e76\u5efa\u8bae')
- w('')
- w('| \u7ec4 | \u76ee\u5f55 | \u5efa\u8bae |')
- w('|------|------|------|')
- dupes = [
- ('\u5546\u57ce', '`store/` vs `hisStore/`', '\u4fdd\u7559 store\uff0chisStore \u653e\u5176\u4ed6'),
- ('\u5546\u57ce', '`store/` vs `his/store*`', 'his \u5185\u5d4c\u5957\u9875\u7559\u5728\u8bca\u6240\u6a21\u5757'),
- ('\u4f1a\u5458', '`user/` `users/` `member/`', '\u5408\u5e76\u4e3a member \u9876\u680f'),
- ('AI', '`fastGpt/` `chat/` `aiob/`', '\u5408\u5e76\u4e3a fastGpt'),
- ('\u5e7f\u544a', '`adv/` `ad/`', '\u7edf\u4e00 adv'),
- ('\u5fae\u4fe1', '`wx/` `gw/`', 'gwAccount \u5f52\u5165 wx'),
- ('\u7edf\u8ba1', '`statistics/` `taskStatistics/`', '\u5408\u5e76 statistics'),
- ('\u76d1\u63a7', '`monitor/` `watch/`', '\u5408\u5e76 watch'),
- ('\u7528\u6237', '`system/user` vs `sysUser/`', 'sysUser \u4ec5\u603b\u540e\u53f0'),
- ]
- for a, b, c in dupes:
- w('| %s | %s | %s |' % (a, b, c))
- w('')
- w('---')
- w('')
- w('## \u516d\u3001\u5b8c\u6574\u4e00\u7ea7\u76ee\u5f55\u626b\u63cf\u8868')
- w('')
- w('| views \u4e00\u7ea7\u76ee\u5f55 | \u53ef\u8def\u7531\u9875\u9762\u6570 | \u5f52\u7c7b |')
- w('|----------------|-------------|------|')
- for top in sorted(by_top.keys()):
- cnt = len(by_top[top])
- if top in ADMIN_ONLY_TOP or top == 'admin':
- cat = '\u5e73\u53f0/\u5176\u4ed6'
- elif top in TENANT_TOP:
- cat = '\u79df\u6237 \u2014 ' + TENANT_TOP[top][0]
- else:
- cat = '\u5f85\u786e\u8ba4'
- w('| `%s/` | %d | %s |' % (top, cnt, cat))
- w('')
- w('---')
- w('')
- w('## \u4e03\u3001\u672c\u6b21\u4e0d\u6267\u884c\u7684\u843d\u5730\u6b65\u9aa4')
- w('')
- w('1. \u8bc4\u5ba1\u672c\u6587\u6863\u4e8c\u7ea7\u5206\u7ec4')
- w('2. \u5bfc\u51fa component \u4e0e tenant_sys_menu diff')
- w('3. \u5408\u5e76\u91cd\u590d\u83dc\u5355')
- w('4. \u66f4\u65b0\u6a21\u677f\u5e76\u540c\u6b65\u79df\u6237\u5e93')
- w('5. saasadminui \u9a8c\u8bc1\u8def\u7531')
- w('')
- w('---')
- w('')
- w('*Generated by `sql/generate_adminUI_menu_doc.py`*')
- return '\n'.join(L)
- def main():
- pages, all_files = scan_views()
- md = build_markdown(pages, all_files)
- with open(OUT, 'w', encoding='utf-8') as f:
- f.write(md)
- print('Wrote', OUT)
- print('pages', len(pages), 'all vue', all_files)
- if __name__ == '__main__':
- main()
|