diff --git a/README.md b/README.md index 6f442ed..77e6c57 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,27 @@ | **entcms** | 企业CMS - 新闻/案例/产品/Banner/线索管理 | | **dingdingflow** | 钉钉审批流程 - 内容发布审批工作流 | +## 目录结构 + +``` +cms/ +├── conf/config.json # 应用配置 +├── wwwroot/ # 前端静态文件(统一目录) +│ ├── index.ui, news.ui, ... # 企业官网页面 +│ ├── api/*.dspy # CMS后端API +│ └── dingdingflow/ # 钉钉审批模块前端 +│ ├── index.ui, menu.ui +│ └── api/*.dspy +├── entcms/ # 企业CMS Python模块 +├── dingdingflow/ # 钉钉审批Python模块 +├── bricks -> pkgs/bricks/dist # 前端框架(符号链接) +├── build.sh # 构建脚本 +├── start.sh / stop.sh # 启停脚本 +├── init_superuser_permissions.py # superuser权限初始化 +├── init_any_permissions.py # any权限初始化 +└── scripts/init_superuser.py # 超级用户账号初始化 +``` + ## 快速开始 ```bash diff --git a/build.sh b/build.sh index 18acd1f..19d8415 100755 --- a/build.sh +++ b/build.sh @@ -186,15 +186,12 @@ echo " 1. 编辑 conf/config.json 填入数据库密码" echo " 2. 执行DDL创建CMS业务表:" echo " mysql -h HOST -u USER -pPASS sage < entcms/mysql.ddl.sql" echo " mysql -h HOST -u USER -pPASS sage < dingdingflow/mysql.ddl.sql" -echo " 3. 加载RBAC权限:" -echo " py3/bin/python entcms/scripts/load_path.py" -echo " py3/bin/python dingdingflow/scripts/load_path.py" -echo " 4. 初始化超级用户:" -echo " py3/bin/python scripts/init_superuser.py" -echo " 5. 初始化权限:" +echo " 3. 初始化权限:" echo " py3/bin/python init_superuser_permissions.py" echo " py3/bin/python init_any_permissions.py" -echo " 6. 启动应用:" +echo " 4. 初始化超级用户:" +echo " py3/bin/python scripts/init_superuser.py" +echo " 5. 启动应用:" echo " ./start.sh" echo "" echo "访问地址: http://localhost:9090/" diff --git a/conf/config.json b/conf/config.json index 504ceb2..a2b158f 100644 --- a/conf/config.json +++ b/conf/config.json @@ -23,13 +23,9 @@ "website": { "paths": [ [ - "$[workdir]$/entcms/wwwroot", + "$[workdir]$/wwwroot", "" ], - [ - "$[workdir]$/dingdingflow/wwwroot", - "/dingdingflow" - ], [ "$[workdir]$/bricks", "/bricks" diff --git a/dingdingflow/scripts/load_path.py b/dingdingflow/scripts/load_path.py index 9914943..cd1c8be 100644 --- a/dingdingflow/scripts/load_path.py +++ b/dingdingflow/scripts/load_path.py @@ -1,74 +1,8 @@ """ -dingdingflow RBAC权限配置 — 企业类型: owner -CMS独立部署,dingdingflow路径保持/dingdingflow前缀 +dingdingflow RBAC权限配置 — 已废弃 -用法: cd ~/repos/cms && py3/bin/python dingdingflow/scripts/load_path.py +dingdingflow模块的wwwroot内容已移到应用根目录的 wwwroot/dingdingflow/ 下。 +请使用: + cd ~/repos/cms && py3/bin/python init_any_permissions.py + cd ~/repos/cms && py3/bin/python init_superuser_permissions.py """ -import os, sys, subprocess - -def find_app_root(): - script_dir = os.path.dirname(os.path.abspath(__file__)) - return os.path.dirname(os.path.dirname(script_dir)) - -app_root = find_app_root() -sage_root = None -for c in [os.path.expanduser("~/repos/sage"), os.path.expanduser("~/sage")]: - if os.path.isdir(os.path.join(c, "py3", "bin")): - sage_root = c - break -if not sage_root: - sage_root = app_root - -py = os.path.join(app_root, "py3", "bin", "python") -sp = os.path.join(sage_root, "set_role_perm.py") if os.path.exists(os.path.join(sage_root, "set_role_perm.py")) else None -if not sp: - print("ERROR: 找不到set_role_perm.py"); sys.exit(1) - -def run(role, paths): - for p in paths: - print(f" {role:30s} {p}") - subprocess.run([py, sp, role, p], cwd=sage_root, capture_output=True) - -any_paths = [ - "/dingdingflow/api/dingtalk_callback.dspy", - "/dingdingflow/menu.ui", -] - -webmaster_paths = [ - "/dingdingflow", - "/dingdingflow/index.ui", - "/dingdingflow/api/submit_approval.dspy", - "/dingdingflow/dd_approvals", "/dingdingflow/dd_approvals/%", - "/dingdingflow/api/dd_approvals_list.dspy", -] - -reviewer_paths = [ - "/dingdingflow", - "/dingdingflow/index.ui", - "/dingdingflow/dd_approvals", "/dingdingflow/dd_approvals/%", - "/dingdingflow/api/dd_approvals_list.dspy", - "/dingdingflow/api/dd_approvals_update.dspy", -] - -supervisor_paths = [ - "/dingdingflow", - "/dingdingflow/index.ui", - "/dingdingflow/dd_approvals", "/dingdingflow/dd_approvals/%", - "/dingdingflow/dd_approval_configs", "/dingdingflow/dd_approval_configs/%", - "/dingdingflow/api/dd_approvals_create.dspy", - "/dingdingflow/api/dd_approvals_update.dspy", - "/dingdingflow/api/dd_approvals_delete.dspy", - "/dingdingflow/api/dd_approvals_list.dspy", - "/dingdingflow/api/dd_approval_configs_create.dspy", - "/dingdingflow/api/dd_approval_configs_update.dspy", - "/dingdingflow/api/dd_approval_configs_delete.dspy", - "/dingdingflow/api/dd_approval_configs_list.dspy", - "/dingdingflow/api/submit_approval.dspy", -] - -print("=== dingdingflow RBAC权限配置 ===") -run("any", any_paths) -run("owner.webmaster", webmaster_paths) -run("owner.reviewer", reviewer_paths) -run("owner.supervisor", supervisor_paths) -print("\n完成") diff --git a/docs/architecture.md b/docs/architecture.md index 05e4d64..b371ffb 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -17,6 +17,22 @@ | cms_leads | 商机线索(网站访客提交 + 未来AI抽取) | | cms_site_config | 站点配置(Hero标语、页脚信息等KV配置) | +**目录结构**: +``` +wwwroot/ # 统一前端目录 +├── index.ui # 官网首页(7个模块:导航/Hero/产品/案例/新闻/页脚/浮动入口) +├── products.ui # 产品架构列表 +├── news.ui # 新闻列表 +├── news_detail.ui # 新闻详情 +├── cases.ui # 案例列表 +├── admin.ui # 管理后台仪表盘 +├── api/*.dspy # CMS后端API +└── dingdingflow/ # 钉钉审批模块 + ├── index.ui + ├── menu.ui + └── api/*.dspy +``` + **公开页面 (any权限)**: - `/index.ui` - 官网首页(7个模块:导航/Hero/产品/案例/新闻/页脚/浮动入口) - `/products.ui` - 产品架构列表 diff --git a/entcms/scripts/load_path.py b/entcms/scripts/load_path.py index 65e7151..f8e3b3d 100644 --- a/entcms/scripts/load_path.py +++ b/entcms/scripts/load_path.py @@ -1,141 +1,8 @@ """ -entcms RBAC权限配置 — 企业类型: owner -CMS独立部署,路径不带/entcms前缀 +entcms RBAC权限配置 — 已废弃 -用法: cd ~/repos/cms && py3/bin/python entcms/scripts/load_path.py +entcms模块的wwwroot内容已移到应用根目录的 wwwroot/ 下。 +请使用: + cd ~/repos/cms && py3/bin/python init_any_permissions.py + cd ~/repos/cms && py3/bin/python init_superuser_permissions.py """ -import os, sys, subprocess - -def find_app_root(): - """查找CMS应用根目录""" - script_dir = os.path.dirname(os.path.abspath(__file__)) - # scripts/ -> entcms/ -> cms root - return os.path.dirname(os.path.dirname(script_dir)) - -app_root = find_app_root() -# 查找Sage的set_role_perm.py(RBAC工具) -sage_root = None -for c in [os.path.expanduser("~/repos/sage"), os.path.expanduser("~/sage")]: - if os.path.isdir(os.path.join(c, "py3", "bin")): - sage_root = c - break -if not sage_root: - # 使用CMS自己的py3 - sage_root = app_root - -py = os.path.join(app_root, "py3", "bin", "python") -sp = os.path.join(sage_root, "set_role_perm.py") if os.path.exists(os.path.join(sage_root, "set_role_perm.py")) else None - -if not sp: - print("ERROR: 找不到set_role_perm.py,请确保Sage或CMS已构建") - sys.exit(1) - -def run(role, paths): - for p in paths: - print(f" {role:30s} {p}") - subprocess.run([py, sp, role, p], cwd=sage_root, capture_output=True) - -# ─── anonymous (any) — 公开页面 + 公开API ─── -any_paths = [ - "/index.ui", - "/news.ui", - "/news_detail.ui", - "/cases.ui", - "/products.ui", - "/cms_styles.css", - "/cms_scripts.js", - "/menu.ui", - "/api/submit_lead.dspy", - "/api/get_config.dspy", - "/api/get_published_content.dspy", - "/api/get_content_detail.dspy", - "/api/get_sections.dspy", -] - -# ─── webmaster — 内容/分类/栏目/配置/线索 全部CRUD ─── -webmaster_paths = [ - "/admin.ui", - # 内容 - "/cms_content_list", "/cms_content_list/%", - "/api/cms_content_create.dspy", - "/api/cms_content_update.dspy", - "/api/cms_content_delete.dspy", - "/api/cms_content_list.dspy", - # 分类 - "/cms_categories_list", "/cms_categories_list/%", - "/api/cms_categories_create.dspy", - "/api/cms_categories_update.dspy", - "/api/cms_categories_delete.dspy", - "/api/cms_categories_list.dspy", - "/api/category_options.dspy", - # 栏目 - "/cms_sections_list", "/cms_sections_list/%", - "/api/cms_sections_create.dspy", - "/api/cms_sections_update.dspy", - "/api/cms_sections_delete.dspy", - "/api/cms_sections_list.dspy", - # 站点配置 - "/cms_site_config_list", "/cms_site_config_list/%", - "/api/cms_site_config_create.dspy", - "/api/cms_site_config_update.dspy", - "/api/cms_site_config_delete.dspy", - "/api/cms_site_config_list.dspy", - # 线索管理 - "/cms_leads_list", "/cms_leads_list/%", - "/api/cms_leads_create.dspy", - "/api/cms_leads_update.dspy", - "/api/cms_leads_delete.dspy", - "/api/cms_leads_list.dspy", - # 审批 - "/api/submit_content_approval.dspy", -] - -# ─── reviewer — 查看内容 + 审批(只改status) ─── -reviewer_paths = [ - "/admin.ui", - "/cms_content_list", "/cms_content_list/%", - "/api/cms_content_list.dspy", - "/api/cms_content_update.dspy", - "/api/category_options.dspy", -] - -# ─── supervisor — 查看全部 + 审批配置 + 线索管理 ─── -supervisor_paths = [ - "/admin.ui", - "/cms_content_list", "/cms_content_list/%", - "/cms_categories_list", "/cms_categories_list/%", - "/cms_sections_list", "/cms_sections_list/%", - "/cms_site_config_list", "/cms_site_config_list/%", - "/api/cms_content_list.dspy", - "/api/cms_categories_list.dspy", - "/api/cms_sections_list.dspy", - "/api/cms_site_config_list.dspy", - "/api/category_options.dspy", - "/cms_leads_list", "/cms_leads_list/%", - "/api/cms_leads_create.dspy", - "/api/cms_leads_update.dspy", - "/api/cms_leads_delete.dspy", - "/api/cms_leads_list.dspy", - "/api/submit_content_approval.dspy", -] - -# ─── customer-support — 线索查看和更新 ─── -support_paths = [ - "/admin.ui", - "/cms_leads_list", "/cms_leads_list/%", - "/api/cms_leads_list.dspy", - "/api/cms_leads_update.dspy", -] - -print("=== CMS RBAC权限配置 ===") -print(f"\n--- any (匿名用户) ---") -run("any", any_paths) -print(f"\n--- owner.webmaster (内容管理员) ---") -run("owner.webmaster", webmaster_paths) -print(f"\n--- owner.reviewer (内容审核) ---") -run("owner.reviewer", reviewer_paths) -print(f"\n--- owner.supervisor (主管) ---") -run("owner.supervisor", supervisor_paths) -print(f"\n--- owner.customer-support (客服) ---") -run("owner.customer-support", support_paths) -print("\n完成") diff --git a/init_any_permissions.py b/init_any_permissions.py index 74f8725..eb5b2c2 100644 --- a/init_any_permissions.py +++ b/init_any_permissions.py @@ -3,8 +3,8 @@ CMS RBAC权限初始化 — any (匿名) 角色 自动扫描 wwwroot 和 bricks 下所有文件,授予 any 角色权限 规则: -- entcms/wwwroot/* → / -- dingdingflow/wwwroot/* → /dingdingflow/ +- wwwroot/* → / +- wwwroot/dingdingflow/* → /dingdingflow/ - bricks/* → /bricks/ - 排除: .pyc, __pycache__, .git, 指向其他模块的符号链接 @@ -108,20 +108,35 @@ print("=== CMS RBAC权限初始化 — any (匿名访问) ===") print(f"Sage: {sage_root}") print() -# 1. entcms/wwwroot → / -entcms_paths = scan_wwwroot( - os.path.join(app_root, "entcms", "wwwroot"), - "" -) -print(f"--- entcms/wwwroot → / ({len(entcms_paths)} 个文件) ---") -n1 = set_any_perms(entcms_paths) +# 1. wwwroot/ 根目录文件 → / (排除dingdingflow子目录) +wwwroot_root = os.path.join(app_root, "wwwroot") +root_paths = [] +if os.path.isdir(wwwroot_root): + for f in sorted(os.listdir(wwwroot_root)): + fpath = os.path.join(wwwroot_root, f) + if os.path.isfile(fpath) and not f.startswith("."): + _, ext = os.path.splitext(f) + if ext.lower() not in SKIP_EXTS: + root_paths.append("/" + f) + # api 子目录 + api_dir = os.path.join(wwwroot_root, "api") + if os.path.isdir(api_dir): + for f in sorted(os.listdir(api_dir)): + fpath = os.path.join(api_dir, f) + if os.path.isfile(fpath) and not f.startswith("."): + _, ext = os.path.splitext(f) + if ext.lower() not in SKIP_EXTS: + root_paths.append("/api/" + f) -# 2. dingdingflow/wwwroot → /dingdingflow +print(f"--- wwwroot/ → / ({len(root_paths)} 个文件) ---") +n1 = set_any_perms(root_paths) + +# 2. wwwroot/dingdingflow/ → /dingdingflow/ dd_paths = scan_wwwroot( - os.path.join(app_root, "dingdingflow", "wwwroot"), + os.path.join(app_root, "wwwroot", "dingdingflow"), "/dingdingflow" ) -print(f"\n--- dingdingflow/wwwroot → /dingdingflow ({len(dd_paths)} 个文件) ---") +print(f"\n--- wwwroot/dingdingflow/ → /dingdingflow ({len(dd_paths)} 个文件) ---") n2 = set_any_perms(dd_paths) # 3. bricks → /bricks diff --git a/init_superuser_permissions.py b/init_superuser_permissions.py index ca3f3ef..ff0af97 100644 --- a/init_superuser_permissions.py +++ b/init_superuser_permissions.py @@ -2,7 +2,7 @@ CMS RBAC权限初始化 — superuser角色 为owner.superuser授予CMS所有权限 -用法: cd ~/repos/cms && py3/bin/python init_superuser.py +用法: cd ~/repos/cms && py3/bin/python init_superuser_permissions.py """ import os, sys, subprocess diff --git a/entcms/wwwroot/admin.ui b/wwwroot/admin.ui similarity index 100% rename from entcms/wwwroot/admin.ui rename to wwwroot/admin.ui diff --git a/entcms/wwwroot/api/category_options.dspy b/wwwroot/api/category_options.dspy similarity index 100% rename from entcms/wwwroot/api/category_options.dspy rename to wwwroot/api/category_options.dspy diff --git a/entcms/wwwroot/api/cms_categories_create.dspy b/wwwroot/api/cms_categories_create.dspy similarity index 100% rename from entcms/wwwroot/api/cms_categories_create.dspy rename to wwwroot/api/cms_categories_create.dspy diff --git a/entcms/wwwroot/api/cms_categories_delete.dspy b/wwwroot/api/cms_categories_delete.dspy similarity index 100% rename from entcms/wwwroot/api/cms_categories_delete.dspy rename to wwwroot/api/cms_categories_delete.dspy diff --git a/entcms/wwwroot/api/cms_categories_list.dspy b/wwwroot/api/cms_categories_list.dspy similarity index 100% rename from entcms/wwwroot/api/cms_categories_list.dspy rename to wwwroot/api/cms_categories_list.dspy diff --git a/entcms/wwwroot/api/cms_categories_update.dspy b/wwwroot/api/cms_categories_update.dspy similarity index 100% rename from entcms/wwwroot/api/cms_categories_update.dspy rename to wwwroot/api/cms_categories_update.dspy diff --git a/entcms/wwwroot/api/cms_content_create.dspy b/wwwroot/api/cms_content_create.dspy similarity index 100% rename from entcms/wwwroot/api/cms_content_create.dspy rename to wwwroot/api/cms_content_create.dspy diff --git a/entcms/wwwroot/api/cms_content_delete.dspy b/wwwroot/api/cms_content_delete.dspy similarity index 100% rename from entcms/wwwroot/api/cms_content_delete.dspy rename to wwwroot/api/cms_content_delete.dspy diff --git a/entcms/wwwroot/api/cms_content_list.dspy b/wwwroot/api/cms_content_list.dspy similarity index 100% rename from entcms/wwwroot/api/cms_content_list.dspy rename to wwwroot/api/cms_content_list.dspy diff --git a/entcms/wwwroot/api/cms_content_update.dspy b/wwwroot/api/cms_content_update.dspy similarity index 100% rename from entcms/wwwroot/api/cms_content_update.dspy rename to wwwroot/api/cms_content_update.dspy diff --git a/entcms/wwwroot/api/cms_leads_create.dspy b/wwwroot/api/cms_leads_create.dspy similarity index 100% rename from entcms/wwwroot/api/cms_leads_create.dspy rename to wwwroot/api/cms_leads_create.dspy diff --git a/entcms/wwwroot/api/cms_leads_delete.dspy b/wwwroot/api/cms_leads_delete.dspy similarity index 100% rename from entcms/wwwroot/api/cms_leads_delete.dspy rename to wwwroot/api/cms_leads_delete.dspy diff --git a/entcms/wwwroot/api/cms_leads_list.dspy b/wwwroot/api/cms_leads_list.dspy similarity index 100% rename from entcms/wwwroot/api/cms_leads_list.dspy rename to wwwroot/api/cms_leads_list.dspy diff --git a/entcms/wwwroot/api/cms_leads_update.dspy b/wwwroot/api/cms_leads_update.dspy similarity index 100% rename from entcms/wwwroot/api/cms_leads_update.dspy rename to wwwroot/api/cms_leads_update.dspy diff --git a/entcms/wwwroot/api/cms_sections_create.dspy b/wwwroot/api/cms_sections_create.dspy similarity index 100% rename from entcms/wwwroot/api/cms_sections_create.dspy rename to wwwroot/api/cms_sections_create.dspy diff --git a/entcms/wwwroot/api/cms_sections_delete.dspy b/wwwroot/api/cms_sections_delete.dspy similarity index 100% rename from entcms/wwwroot/api/cms_sections_delete.dspy rename to wwwroot/api/cms_sections_delete.dspy diff --git a/entcms/wwwroot/api/cms_sections_list.dspy b/wwwroot/api/cms_sections_list.dspy similarity index 100% rename from entcms/wwwroot/api/cms_sections_list.dspy rename to wwwroot/api/cms_sections_list.dspy diff --git a/entcms/wwwroot/api/cms_sections_update.dspy b/wwwroot/api/cms_sections_update.dspy similarity index 100% rename from entcms/wwwroot/api/cms_sections_update.dspy rename to wwwroot/api/cms_sections_update.dspy diff --git a/entcms/wwwroot/api/cms_site_config_create.dspy b/wwwroot/api/cms_site_config_create.dspy similarity index 100% rename from entcms/wwwroot/api/cms_site_config_create.dspy rename to wwwroot/api/cms_site_config_create.dspy diff --git a/entcms/wwwroot/api/cms_site_config_delete.dspy b/wwwroot/api/cms_site_config_delete.dspy similarity index 100% rename from entcms/wwwroot/api/cms_site_config_delete.dspy rename to wwwroot/api/cms_site_config_delete.dspy diff --git a/entcms/wwwroot/api/cms_site_config_list.dspy b/wwwroot/api/cms_site_config_list.dspy similarity index 100% rename from entcms/wwwroot/api/cms_site_config_list.dspy rename to wwwroot/api/cms_site_config_list.dspy diff --git a/entcms/wwwroot/api/cms_site_config_update.dspy b/wwwroot/api/cms_site_config_update.dspy similarity index 100% rename from entcms/wwwroot/api/cms_site_config_update.dspy rename to wwwroot/api/cms_site_config_update.dspy diff --git a/entcms/wwwroot/api/get_config.dspy b/wwwroot/api/get_config.dspy similarity index 100% rename from entcms/wwwroot/api/get_config.dspy rename to wwwroot/api/get_config.dspy diff --git a/entcms/wwwroot/api/get_content_detail.dspy b/wwwroot/api/get_content_detail.dspy similarity index 100% rename from entcms/wwwroot/api/get_content_detail.dspy rename to wwwroot/api/get_content_detail.dspy diff --git a/entcms/wwwroot/api/get_published_content.dspy b/wwwroot/api/get_published_content.dspy similarity index 100% rename from entcms/wwwroot/api/get_published_content.dspy rename to wwwroot/api/get_published_content.dspy diff --git a/entcms/wwwroot/api/get_sections.dspy b/wwwroot/api/get_sections.dspy similarity index 100% rename from entcms/wwwroot/api/get_sections.dspy rename to wwwroot/api/get_sections.dspy diff --git a/entcms/wwwroot/api/submit_content_approval.dspy b/wwwroot/api/submit_content_approval.dspy similarity index 100% rename from entcms/wwwroot/api/submit_content_approval.dspy rename to wwwroot/api/submit_content_approval.dspy diff --git a/entcms/wwwroot/api/submit_lead.dspy b/wwwroot/api/submit_lead.dspy similarity index 100% rename from entcms/wwwroot/api/submit_lead.dspy rename to wwwroot/api/submit_lead.dspy diff --git a/entcms/wwwroot/cases.ui b/wwwroot/cases.ui similarity index 100% rename from entcms/wwwroot/cases.ui rename to wwwroot/cases.ui diff --git a/entcms/wwwroot/cms_scripts.js b/wwwroot/cms_scripts.js similarity index 100% rename from entcms/wwwroot/cms_scripts.js rename to wwwroot/cms_scripts.js diff --git a/entcms/wwwroot/cms_styles.css b/wwwroot/cms_styles.css similarity index 100% rename from entcms/wwwroot/cms_styles.css rename to wwwroot/cms_styles.css diff --git a/dingdingflow/wwwroot/api/dd_approval_configs_create.dspy b/wwwroot/dingdingflow/api/dd_approval_configs_create.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approval_configs_create.dspy rename to wwwroot/dingdingflow/api/dd_approval_configs_create.dspy diff --git a/dingdingflow/wwwroot/api/dd_approval_configs_delete.dspy b/wwwroot/dingdingflow/api/dd_approval_configs_delete.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approval_configs_delete.dspy rename to wwwroot/dingdingflow/api/dd_approval_configs_delete.dspy diff --git a/dingdingflow/wwwroot/api/dd_approval_configs_list.dspy b/wwwroot/dingdingflow/api/dd_approval_configs_list.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approval_configs_list.dspy rename to wwwroot/dingdingflow/api/dd_approval_configs_list.dspy diff --git a/dingdingflow/wwwroot/api/dd_approval_configs_update.dspy b/wwwroot/dingdingflow/api/dd_approval_configs_update.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approval_configs_update.dspy rename to wwwroot/dingdingflow/api/dd_approval_configs_update.dspy diff --git a/dingdingflow/wwwroot/api/dd_approvals_create.dspy b/wwwroot/dingdingflow/api/dd_approvals_create.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approvals_create.dspy rename to wwwroot/dingdingflow/api/dd_approvals_create.dspy diff --git a/dingdingflow/wwwroot/api/dd_approvals_delete.dspy b/wwwroot/dingdingflow/api/dd_approvals_delete.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approvals_delete.dspy rename to wwwroot/dingdingflow/api/dd_approvals_delete.dspy diff --git a/dingdingflow/wwwroot/api/dd_approvals_list.dspy b/wwwroot/dingdingflow/api/dd_approvals_list.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approvals_list.dspy rename to wwwroot/dingdingflow/api/dd_approvals_list.dspy diff --git a/dingdingflow/wwwroot/api/dd_approvals_update.dspy b/wwwroot/dingdingflow/api/dd_approvals_update.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dd_approvals_update.dspy rename to wwwroot/dingdingflow/api/dd_approvals_update.dspy diff --git a/dingdingflow/wwwroot/api/dingtalk_callback.dspy b/wwwroot/dingdingflow/api/dingtalk_callback.dspy similarity index 100% rename from dingdingflow/wwwroot/api/dingtalk_callback.dspy rename to wwwroot/dingdingflow/api/dingtalk_callback.dspy diff --git a/dingdingflow/wwwroot/api/submit_approval.dspy b/wwwroot/dingdingflow/api/submit_approval.dspy similarity index 100% rename from dingdingflow/wwwroot/api/submit_approval.dspy rename to wwwroot/dingdingflow/api/submit_approval.dspy diff --git a/dingdingflow/wwwroot/index.ui b/wwwroot/dingdingflow/index.ui similarity index 100% rename from dingdingflow/wwwroot/index.ui rename to wwwroot/dingdingflow/index.ui diff --git a/dingdingflow/wwwroot/menu.ui b/wwwroot/dingdingflow/menu.ui similarity index 100% rename from dingdingflow/wwwroot/menu.ui rename to wwwroot/dingdingflow/menu.ui diff --git a/entcms/wwwroot/index.ui b/wwwroot/index.ui similarity index 100% rename from entcms/wwwroot/index.ui rename to wwwroot/index.ui diff --git a/entcms/wwwroot/menu.ui b/wwwroot/menu.ui similarity index 100% rename from entcms/wwwroot/menu.ui rename to wwwroot/menu.ui diff --git a/entcms/wwwroot/news.ui b/wwwroot/news.ui similarity index 100% rename from entcms/wwwroot/news.ui rename to wwwroot/news.ui diff --git a/entcms/wwwroot/news_detail.ui b/wwwroot/news_detail.ui similarity index 100% rename from entcms/wwwroot/news_detail.ui rename to wwwroot/news_detail.ui diff --git a/entcms/wwwroot/products.ui b/wwwroot/products.ui similarity index 100% rename from entcms/wwwroot/products.ui rename to wwwroot/products.ui