feat(address): 新增收货地址与售后申请功能

- 新增地址编辑页面,支持地址智能识别、地图选点、地区选择和默认地址设置
- 实现地址列表页面,支持地址查看、删除、设为默认及选择返回结算页
- 新增售后申请页面,支持退款类型选择、商品选择、原因填写、图片上传和提交审核
- 修复 passport 分包配置,移除不存在分包并补充缺失声明,避免 Taro 编译报错
- 新增地址类型定义,增强前端地址数据结构类型安全
- 优化页面交互体验,完善表单校验及错误提示逻辑
- 统一代码格式与命名规范,保持代码风格一致性
This commit is contained in:
2026-07-16 01:18:42 +08:00
commit 9df90c1176
658 changed files with 85984 additions and 0 deletions

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

556
.idea/workspace.xml generated Normal file
View File

@@ -0,0 +1,556 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="2de94e4f-0587-4c9b-8bfd-e87e0ae95b81" name="更改" comment="feat(pay-bak): 新增小程序支付页面及相关配置&#10;&#10;- 新增确认支付页面配置,设置导航栏标题和样式&#10;- 实现小程序支付页完整组件逻辑包括加载订单、发起JSAPI支付等&#10;- 支持通过 scene 或 subscriptionNo 获取订单参数&#10;- 完善支付流程接口请求及错误处理,支持自动登录和支付确认&#10;- 增加支付成功、支付中、支付失败、取消等状态页面展示&#10;- 支持支付成功后跳转已购产品页或用户页&#10;- 提供取消支付返回逻辑和界面展示&#10;- 细化支付金额显示和提示用户支付后可使用应用功能" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
<option name="RESET_MODE" value="HARD" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 7
}</component>
<component name="ProjectId" id="3CCElusNNIyc7lgX61jkNQo02h3" />
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"git-widget-placeholder": "master",
"junie.onboarding.icon.badge.shown": "true",
"last_opened_file_path": "/Users/gxwebsoft/VUE/websopy-taro/src/passport",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "pnpm",
"npm.build:weapp.executor": "Run",
"npm.dev:weapp.executor": "Run",
"settings.editor.selected.configurable": "preferences.pluginManager",
"to.speed.mode.migration.done": "true",
"ts.external.directory.path": "/Applications/WebStorm.app/Contents/plugins/javascript-plugin/jsLanguageServicesImpl/external",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src/passport" />
<recent name="$PROJECT_DIR$/src/api" />
<recent name="$PROJECT_DIR$/src/api/passport/wx-login" />
<recent name="$PROJECT_DIR$" />
</key>
</component>
<component name="RunManager" selected="npm.build:weapp">
<configuration name="build:weapp" type="js.build_tools.npm" temporary="true" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="build:weapp" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
<configuration name="dev:weapp" type="js.build_tools.npm" temporary="true" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="dev:weapp" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="npm.build:weapp" />
<item itemvalue="npm.dev:weapp" />
</list>
</recent_temporary>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-d6986cc7102b-e03c56caf84a-JavaScript-WS-252.23892.411" />
</set>
</attachedChunks>
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="2de94e4f-0587-4c9b-8bfd-e87e0ae95b81" name="更改" comment="" />
<created>1775881305279</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1775881305279</updated>
<workItem from="1775881306434" duration="12652000" />
<workItem from="1775910653750" duration="20840000" />
<workItem from="1777873063244" duration="20000" />
<workItem from="1778089953570" duration="7000" />
<workItem from="1778308774420" duration="947000" />
<workItem from="1780559793276" duration="400000" />
<workItem from="1782803615391" duration="418000" />
<workItem from="1782804285999" duration="4025000" />
<workItem from="1782813891753" duration="1850000" />
<workItem from="1782876148090" duration="4787000" />
<workItem from="1782903749109" duration="4000" />
<workItem from="1782971387128" duration="7154000" />
<workItem from="1784093204572" duration="6082000" />
<workItem from="1784131049625" duration="2304000" />
<workItem from="1784133736973" duration="2124000" />
</task>
<task id="LOCAL-00005" summary="fix(passport): 修正邀请接受接口的URL路径&#10;&#10;- 将邀请接受接口URL从/api/_app/invite/accept修改为/api/_app/developer/invite/accept&#10;- 确保请求正确指向开发者邀请接受接口&#10;- 修复因URL错误导致的邀请接受失败问题">
<option name="closed" value="true" />
<created>1775896148590</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1775896148590</updated>
</task>
<task id="LOCAL-00006" summary="fix(passport): 修正邀请接受接口的URL路径&#10;&#10;- 将邀请接受接口URL从/api/_app/invite/accept修改为/api/_app/developer/invite/accept&#10;- 确保请求正确指向开发者邀请接受接口&#10;- 修复因URL错误导致的邀请接受失败问题">
<option name="closed" value="true" />
<created>1775901973624</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1775901973624</updated>
</task>
<task id="LOCAL-00007" summary="fix(passport): 优化登录确认成功后的页面跳转逻辑&#10;&#10;- 延长登录确认成功提示的显示时间至2000毫秒&#10;- 跳转到用户页面前先隐藏toast避免影响跳转体验&#10;- 增加switchTab成功和失败的日志打印&#10;- 失败时提示用户手动返回页面&#10;- 调整跳转延迟时间为1800毫秒提升交互流畅度">
<option name="closed" value="true" />
<created>1775902053962</created>
<option name="number" value="00007" />
<option name="presentableId" value="LOCAL-00007" />
<option name="project" value="LOCAL" />
<updated>1775902053962</updated>
</task>
<task id="LOCAL-00008" summary="fix(passport): 修正邀请信息接口请求参数与请求头&#10;&#10;- 将邀请令牌作为查询参数附加在请求URL中&#10;- 移除请求体中的token字段传递&#10;- 添加请求头TenantId值为5&#10;- 请求失败时在控制台打印错误信息以便调试&#10;- 保持原有错误处理和加载状态设置逻辑不变">
<option name="closed" value="true" />
<created>1775904794443</created>
<option name="number" value="00008" />
<option name="presentableId" value="LOCAL-00008" />
<option name="project" value="LOCAL" />
<updated>1775904794443</updated>
</task>
<task id="LOCAL-00009" summary="fix(invite): 修复邀请加入请求头TenantId传递问题&#10;&#10;- 从配置中引入TenantId常量&#10;- 将请求header中的TenantId字段由硬编码改为动态变量&#10;- 确保GET请求和加密数据请求均正确带上TenantId头信息&#10;- 提升接口调用的一致性和维护性">
<option name="closed" value="true" />
<created>1775905047844</created>
<option name="number" value="00009" />
<option name="presentableId" value="LOCAL-00009" />
<option name="project" value="LOCAL" />
<updated>1775905047844</updated>
</task>
<task id="LOCAL-00010" summary="fix(config): 修正环境配置中的API_BASE_URL地址&#10;&#10;- 将开发环境、生产环境和测试环境的API_BASE_URL统一更新为新的域名websopy-api.websoft.top&#10;- 更新SimpleQRCodeModal组件中二维码请求地址使用新的API域名&#10;- 在邀请信息请求函数fetchInviteInfo中添加详细的请求和响应日志&#10;- 增加接口错误日志打印,提高捕获异常时的信息丰富度">
<option name="closed" value="true" />
<created>1775905427131</created>
<option name="number" value="00010" />
<option name="presentableId" value="LOCAL-00010" />
<option name="project" value="LOCAL" />
<updated>1775905427131</updated>
</task>
<task id="LOCAL-00011" summary="fix(invite): 修正邀请接口使用独立API域名&#10;&#10;- 将邀请相关接口的请求地址由通用API域名改为独立的INVITE_API_URL&#10;- 修改获取邀请信息接口的请求URL&#10;- 修改接受邀请接口的请求URL&#10;- 确保请求头和参数传递保持一致">
<option name="closed" value="true" />
<created>1775905743204</created>
<option name="number" value="00011" />
<option name="presentableId" value="LOCAL-00011" />
<option name="project" value="LOCAL" />
<updated>1775905743204</updated>
</task>
<task id="LOCAL-00012" summary="refactor(api): 移除未使用的配置接口及相关Hook&#10;&#10;- 从cmsWebsiteField接口中删除configWebsiteField方法&#10;- 删除useConfig自定义Hook及其引用&#10;- 更新about页面去除对config对象和useConfig的使用&#10;- 修正invite模块请求URL统一加上/api前缀">
<option name="closed" value="true" />
<created>1775908253789</created>
<option name="number" value="00012" />
<option name="presentableId" value="LOCAL-00012" />
<option name="project" value="LOCAL" />
<updated>1775908253789</updated>
</task>
<task id="LOCAL-00013" summary="refactor(api): 移除未使用的配置接口及相关Hook&#10;&#10;- 从cmsWebsiteField接口中删除configWebsiteField方法&#10;- 删除useConfig自定义Hook及其引用&#10;- 更新about页面去除对config对象和useConfig的使用&#10;- 修正invite模块请求URL统一加上/api前缀">
<option name="closed" value="true" />
<created>1775908391880</created>
<option name="number" value="00013" />
<option name="presentableId" value="LOCAL-00013" />
<option name="project" value="LOCAL" />
<updated>1775908391880</updated>
</task>
<task id="LOCAL-00014" summary="fix(invite): 修正邀请接口路径以支持小程序专用前缀&#10;&#10;- 将请求邀请信息接口路径改为使用 /api/_app 前缀,确保小程序免登录访问&#10;- 修改接受邀请接口路径,统一使用小程序专用 API 域名和前缀&#10;- 更新邀请相关接口注释,明确小程序专用接口前缀含义&#10;- 在专家历史数据中添加高级开发工程师 Will 的条目并更新时间戳">
<option name="closed" value="true" />
<created>1775909013060</created>
<option name="number" value="00014" />
<option name="presentableId" value="LOCAL-00014" />
<option name="project" value="LOCAL" />
<updated>1775909013060</updated>
</task>
<task id="LOCAL-00015" summary="fix(passport): 添加邀请接受接口调试日志&#10;&#10;- 在接受邀请请求前打印token和请求URL、参数&#10;- 在请求响应后输出接口响应及返回数据&#10;- 在调用失败时打印错误信息及异常日志&#10;- 保持请求流程和状态管理不变,增强调试能力">
<option name="closed" value="true" />
<created>1775909542310</created>
<option name="number" value="00015" />
<option name="presentableId" value="LOCAL-00015" />
<option name="project" value="LOCAL" />
<updated>1775909542310</updated>
</task>
<task id="LOCAL-00016" summary="fix(passport): 添加邀请接受接口调试日志&#10;&#10;- 在接受邀请请求前打印token和请求URL、参数&#10;- 在请求响应后输出接口响应及返回数据&#10;- 在调用失败时打印错误信息及异常日志&#10;- 保持请求流程和状态管理不变,增强调试能力">
<option name="closed" value="true" />
<created>1775909811705</created>
<option name="number" value="00016" />
<option name="presentableId" value="LOCAL-00016" />
<option name="project" value="LOCAL" />
<updated>1775909811705</updated>
</task>
<task id="LOCAL-00017" summary="fix(passport): 优化邀请码接受失败的用户提示和处理&#10;&#10;- 针对“用户不存在”、“用户创建失败”及“请先登录”提示,改为弹窗提示需登录&#10;- 在弹窗中增加“去登录”按钮点击后跳转到登录页面并携带重定向token参数&#10;- 其他错误仍使用原Toast提示方式展示错误信息&#10;- 保留错误日志打印,便于排查异常情况">
<option name="closed" value="true" />
<created>1775920899787</created>
<option name="number" value="00017" />
<option name="presentableId" value="LOCAL-00017" />
<option name="project" value="LOCAL" />
<updated>1775920899787</updated>
</task>
<task id="LOCAL-00018" summary="feat(passport-invite): 优化新用户扫码邀请加入流程&#10;&#10;- 扫码进入邀请页面时保存邀请 token 到本地存储&#10;- 新增登录状态检测,未登录用户点击快速加入时保存邀请信息并跳转登录页&#10;- 登录成功后返回邀请页自动执行加入应用操作,提升用户体验&#10;- 支持已登录用户直接加入应用,简化流程&#10;- 增加清理 pending 邀请数据的方法,防止数据残留&#10;- 监听页面显示事件,处理登录返回后自动操作&#10;- 调整接口请求逻辑,确保携带最新的邀请和授权数据&#10;- 更新项目配置,注册邀请页面路径信息">
<option name="closed" value="true" />
<created>1775921636640</created>
<option name="number" value="00018" />
<option name="presentableId" value="LOCAL-00018" />
<option name="project" value="LOCAL" />
<updated>1775921636640</updated>
</task>
<task id="LOCAL-00019" summary="feat(passport): 重写登录与邀请加入流程,支持微信手机号一键登录&#10;&#10;- 完全重写 passport/login.tsx实现微信手机号一键登录功能&#10;- 支持登录页面携带 redirect 参数,登录后自动跳转回原页面&#10;- 登录成功后自动处理邀请加入应用,支持邀请关系绑定&#10;- 重写 passport/invite/index.tsx实现扫码邀请加入应用完整流程&#10;- 支持调用 wx.login 获取 code使用 loginByOpenId 判断注册状态&#10;- 未注册用户自动跳转登录页完成微信手机号登录再加入应用&#10;- 已登录用户直接执行加入应用操作,加入接口支持 Authorization 头&#10;- 解决邀请页面与登录页面间旧授权码混用导致加入失败问题&#10;- 处理后端 401 错误,优先使用微信授权码免登录接口&#10;- 优化用户体验,添加服务协议与隐私政策弹窗及错误提示&#10;- 页面状态管理改进,加入加载、检查登录、错误和跳转反馈">
<option name="closed" value="true" />
<created>1775962292970</created>
<option name="number" value="00019" />
<option name="presentableId" value="LOCAL-00019" />
<option name="project" value="LOCAL" />
<updated>1775962292970</updated>
</task>
<task id="LOCAL-00020" summary="feat(invite): 重构邀请加入流程,实现已登录用户免授权直接加入&#10;&#10;- 完全重写邀请页逻辑,区分已登录与未注册用户按钮显示&#10;- 已登录用户显示“确认加入”按钮,点击用 wx.login 获取 code 加入&#10;- 未注册用户显示“微信手机号快速加入”按钮,授权手机号后完成注册登录再加入&#10;- 移除跳转登录页面逻辑,所有流程在邀请页内完成&#10;- 加入接口统一使用 Authorization 头携带 token确保身份双重验证&#10;- 优化背景、粒子和扫描线效果,提升界面视觉体验&#10;- 增加错误处理提示,加入失败时显示详细原因并可返回首页&#10;- 协议勾选仅在未注册用户显示,确保合规授权流程">
<option name="closed" value="true" />
<created>1775965322794</created>
<option name="number" value="00020" />
<option name="presentableId" value="LOCAL-00020" />
<option name="project" value="LOCAL" />
<updated>1775965322794</updated>
</task>
<task id="LOCAL-00021" summary="feat(passport): 优化已登录用户加入时协议勾选逻辑&#10;&#10;- 已登录用户点击「确认加入」时不再强制勾选协议&#10;- 移除 handleConfirmJoin 中对协议勾选的检查&#10;- 未注册用户仍需勾选协议后才能授权手机号&#10;- 确保登录状态异常时有提示信息显示">
<option name="closed" value="true" />
<created>1775965478226</created>
<option name="number" value="00021" />
<option name="presentableId" value="LOCAL-00021" />
<option name="project" value="LOCAL" />
<updated>1775965478226</updated>
</task>
<task id="LOCAL-00022" summary="feat(invite): 支持已登录用户直接加入应用&#10;&#10;- 后端accept接口code参数改为可选支持通过Authorization头识别登录用户&#10;- 已登录用户加入时不再弹手机号授权前端调用新增的doJoinAppForLoggedInUser方法&#10;- 未注册用户仍通过手机号授权码code加入调用doJoinAppForNewUser方法&#10;- 拆分前端加入逻辑新增handleConfirmJoin统一处理已登录加入流程&#10;- 优化按钮交互,已登录状态下按钮变为普通点击,移除协议强制勾选&#10;- 错误处理和状态提示完善,加入成功后自动跳转首页">
<option name="closed" value="true" />
<created>1775966172496</created>
<option name="number" value="00022" />
<option name="presentableId" value="LOCAL-00022" />
<option name="project" value="LOCAL" />
<updated>1775966172496</updated>
</task>
<task id="LOCAL-00023" summary="feat(developer): 完成小程序开发者中心和企业控制台改造&#10;&#10;- 设计并实现了开发者中心与企业控制台两大模块&#10;- 按用户角色区分开发者和企业客户,支持多项目类型及成员管理&#10;- 新增项目管理、应用管理、API Key管理及成员邀请等多功能页面&#10;- 实现应用版本发布、消息通知中心、权限审批与开发者申请流程&#10;- 完成CI/CD流水线、运营监控、发票管理、SSO单点登录功能&#10;- 搭建SDK下载中心、工单系统、FAQ系统、数据导入导出等模块&#10;- 优化后端API支持已登录和未注册用户不同加入应用流程&#10;- 前端按钮统一采用微信手机号授权,完善用户授权体验&#10;- 修复多个页面的JSX语法错误及依赖导入问题替换部分组件库&#10;- 增加详细的类型定义文件,提升项目类型安全&#10;- 新增超过55个页面及60个API接口扩展应用功能和服务体系&#10;- 完成全面的样式设计,实现一致的视觉风格和交互体验">
<option name="closed" value="true" />
<created>1776018406658</created>
<option name="number" value="00023" />
<option name="presentableId" value="LOCAL-00023" />
<option name="project" value="LOCAL" />
<updated>1776018406658</updated>
</task>
<task id="LOCAL-00024" summary="feat(api-keys): 优化隐私协议同意逻辑及样式&#10;&#10;- 修正api-keys样式导入路径改为developer路径&#10;- 在开发者申请页面增加服务协议和隐私政策勾选框&#10;- 提交时校验协议是否已勾选,未勾选时提示用户&#10;- 优化申请页面协议区域样式及交互&#10;- 在用户验证页面添加隐私政策同意勾选框&#10;- 提交用户验证表单时检查协议同意状态&#10;- 增加打开服务协议和隐私政策的链接跳转&#10;- 更新项目配置增加passport/webview路由配置&#10;- 修复createTicket函数中日期格式正则表达式问题">
<option name="closed" value="true" />
<created>1776019228297</created>
<option name="number" value="00024" />
<option name="presentableId" value="LOCAL-00024" />
<option name="project" value="LOCAL" />
<updated>1776019228297</updated>
</task>
<task id="LOCAL-00025" summary="feat(api-keys): 优化隐私协议同意逻辑及样式&#10;&#10;- 修正api-keys样式导入路径改为developer路径&#10;- 在开发者申请页面增加服务协议和隐私政策勾选框&#10;- 提交时校验协议是否已勾选,未勾选时提示用户&#10;- 优化申请页面协议区域样式及交互&#10;- 在用户验证页面添加隐私政策同意勾选框&#10;- 提交用户验证表单时检查协议同意状态&#10;- 增加打开服务协议和隐私政策的链接跳转&#10;- 更新项目配置增加passport/webview路由配置&#10;- 修复createTicket函数中日期格式正则表达式问题">
<option name="closed" value="true" />
<created>1776019711439</created>
<option name="number" value="00025" />
<option name="presentableId" value="LOCAL-00025" />
<option name="project" value="LOCAL" />
<updated>1776019711439</updated>
</task>
<task id="LOCAL-00026" summary="refactor(config): 移除开发者中心和企业控制台的自定义导航样式&#10;&#10;- 删除了开发者中心页面配置中的 navigationStyle: 'custom'&#10;- 删除了企业控制台页面配置中的 navigationStyle: 'custom'&#10;- 简化了页面配置,保持默认导航样式&#10;- 有助于提升页面兼容性和维护性">
<option name="closed" value="true" />
<created>1776019857647</created>
<option name="number" value="00026" />
<option name="presentableId" value="LOCAL-00026" />
<option name="project" value="LOCAL" />
<updated>1776019857647</updated>
</task>
<task id="LOCAL-00027" summary="feat(userVerify): 添加阿里云身份证二要素核验功能&#10;&#10;- 在接口层新增 verifyIdCard 接口,实现姓名与身份证号核验&#10;- userVerify 页面提交时增加身份核验逻辑,核验失败阻止提交&#10;- 调用核验接口时显示加载状态,并根据结果提示用户&#10;- 后端依赖 aliyun cloudauth提供实人认证相关服务接口&#10;- 完成基本的错误捕获与用户提示,提升实名认证流程安全性">
<option name="closed" value="true" />
<created>1776021606260</created>
<option name="number" value="00027" />
<option name="presentableId" value="LOCAL-00027" />
<option name="project" value="LOCAL" />
<updated>1776021606260</updated>
</task>
<task id="LOCAL-00028" summary="feat(userVerify): 添加阿里云身份证二要素核验功能&#10;&#10;- 在接口层新增 verifyIdCard 接口,实现姓名与身份证号核验&#10;- userVerify 页面提交时增加身份核验逻辑,核验失败阻止提交&#10;- 调用核验接口时显示加载状态,并根据结果提示用户&#10;- 后端依赖 aliyun cloudauth提供实人认证相关服务接口&#10;- 完成基本的错误捕获与用户提示,提升实名认证流程安全性">
<option name="closed" value="true" />
<created>1776021764419</created>
<option name="number" value="00028" />
<option name="presentableId" value="LOCAL-00028" />
<option name="project" value="LOCAL" />
<updated>1776021764419</updated>
</task>
<task id="LOCAL-00029" summary="refactor(api): 规范前端API接口地址并统一路径前缀&#10;&#10;- 修正开发者、小程序和企业相关API的基础URL避免重复添加/api前缀&#10;- 统一调整developer、enterprise、invite等模块接口路径保持与后端Controller一致&#10;- 新增权限申请及消息通知相关API并完善相关函数实现&#10;- 规范请求参数传递,移除多余包装,改用直接传递对象方式&#10;- 新增API Key重置、版本发布/回滚等接口支持&#10;&#10;feat(invite): 重构邀请登录流程支持未注册快速加入&#10;&#10;- 完整重写invite页分离已注册用户和未注册用户的按钮显示和交互&#10;- 实现未注册用户微信手机号授权后自动注册登录及自动加入应用&#10;- 已注册用户直接确认加入应用,无需手机号授权弹窗&#10;- 统一使用getPhoneNumber按钮处理两种状态并修复“授权码不能为空”报错&#10;- 前端配合后端改造支持已登录用户可直接通过Authorization头加入应用&#10;&#10;fix(developer): 修复开发者中心应用加载问题&#10;&#10;- 修复只查询创建的应用导致邀请加入的应用不显示的问题&#10;- 同时请求创建应用和参与应用接口,合并并去重应用列表&#10;- 新增pageJoinedApp接口调用及合并逻辑提高应用列表完整性和体验">
<option name="closed" value="true" />
<created>1776065433562</created>
<option name="number" value="00029" />
<option name="presentableId" value="LOCAL-00029" />
<option name="project" value="LOCAL" />
<updated>1776065433562</updated>
</task>
<task id="LOCAL-00030" summary="refactor(api): 规范前端API接口地址并统一路径前缀&#10;&#10;- 修正开发者、小程序和企业相关API的基础URL避免重复添加/api前缀&#10;- 统一调整developer、enterprise、invite等模块接口路径保持与后端Controller一致&#10;- 新增权限申请及消息通知相关API并完善相关函数实现&#10;- 规范请求参数传递,移除多余包装,改用直接传递对象方式&#10;- 新增API Key重置、版本发布/回滚等接口支持&#10;&#10;feat(invite): 重构邀请登录流程支持未注册快速加入&#10;&#10;- 完整重写invite页分离已注册用户和未注册用户的按钮显示和交互&#10;- 实现未注册用户微信手机号授权后自动注册登录及自动加入应用&#10;- 已注册用户直接确认加入应用,无需手机号授权弹窗&#10;- 统一使用getPhoneNumber按钮处理两种状态并修复“授权码不能为空”报错&#10;- 前端配合后端改造支持已登录用户可直接通过Authorization头加入应用&#10;&#10;fix(developer): 修复开发者中心应用加载问题&#10;&#10;- 修复只查询创建的应用导致邀请加入的应用不显示的问题&#10;- 同时请求创建应用和参与应用接口,合并并去重应用列表&#10;- 新增pageJoinedApp接口调用及合并逻辑提高应用列表完整性和体验">
<option name="closed" value="true" />
<created>1782803958326</created>
<option name="number" value="00030" />
<option name="presentableId" value="LOCAL-00030" />
<option name="project" value="LOCAL" />
<updated>1782803958326</updated>
</task>
<task id="LOCAL-00031" summary="refactor(api): 规范前端API接口地址并统一路径前缀&#10;&#10;- 修正开发者、小程序和企业相关API的基础URL避免重复添加/api前缀&#10;- 统一调整developer、enterprise、invite等模块接口路径保持与后端Controller一致&#10;- 新增权限申请及消息通知相关API并完善相关函数实现&#10;- 规范请求参数传递,移除多余包装,改用直接传递对象方式&#10;- 新增API Key重置、版本发布/回滚等接口支持&#10;&#10;feat(invite): 重构邀请登录流程支持未注册快速加入&#10;&#10;- 完整重写invite页分离已注册用户和未注册用户的按钮显示和交互&#10;- 实现未注册用户微信手机号授权后自动注册登录及自动加入应用&#10;- 已注册用户直接确认加入应用,无需手机号授权弹窗&#10;- 统一使用getPhoneNumber按钮处理两种状态并修复“授权码不能为空”报错&#10;- 前端配合后端改造支持已登录用户可直接通过Authorization头加入应用&#10;&#10;fix(developer): 修复开发者中心应用加载问题&#10;&#10;- 修复只查询创建的应用导致邀请加入的应用不显示的问题&#10;- 同时请求创建应用和参与应用接口,合并并去重应用列表&#10;- 新增pageJoinedApp接口调用及合并逻辑提高应用列表完整性和体验">
<option name="closed" value="true" />
<created>1782803960387</created>
<option name="number" value="00031" />
<option name="presentableId" value="LOCAL-00031" />
<option name="project" value="LOCAL" />
<updated>1782803960387</updated>
</task>
<task id="LOCAL-00032" summary="refactor(api): 规范前端API接口地址并统一路径前缀&#10;&#10;- 修正开发者、小程序和企业相关API的基础URL避免重复添加/api前缀&#10;- 统一调整developer、enterprise、invite等模块接口路径保持与后端Controller一致&#10;- 新增权限申请及消息通知相关API并完善相关函数实现&#10;- 规范请求参数传递,移除多余包装,改用直接传递对象方式&#10;- 新增API Key重置、版本发布/回滚等接口支持&#10;&#10;feat(invite): 重构邀请登录流程支持未注册快速加入&#10;&#10;- 完整重写invite页分离已注册用户和未注册用户的按钮显示和交互&#10;- 实现未注册用户微信手机号授权后自动注册登录及自动加入应用&#10;- 已注册用户直接确认加入应用,无需手机号授权弹窗&#10;- 统一使用getPhoneNumber按钮处理两种状态并修复“授权码不能为空”报错&#10;- 前端配合后端改造支持已登录用户可直接通过Authorization头加入应用&#10;&#10;fix(developer): 修复开发者中心应用加载问题&#10;&#10;- 修复只查询创建的应用导致邀请加入的应用不显示的问题&#10;- 同时请求创建应用和参与应用接口,合并并去重应用列表&#10;- 新增pageJoinedApp接口调用及合并逻辑提高应用列表完整性和体验">
<option name="closed" value="true" />
<created>1782803963602</created>
<option name="number" value="00032" />
<option name="presentableId" value="LOCAL-00032" />
<option name="project" value="LOCAL" />
<updated>1782803963602</updated>
</task>
<task id="LOCAL-00033" summary="feat(app): 添加应用入口文件和配置文件&#10;&#10;- 新增 index.tsx 作为应用的主入口文件&#10;- 新增 index.config.ts 用于应用的配置管理">
<option name="closed" value="true" />
<created>1782804027400</created>
<option name="number" value="00033" />
<option name="presentableId" value="LOCAL-00033" />
<option name="project" value="LOCAL" />
<updated>1782804027400</updated>
</task>
<task id="LOCAL-00034" summary="feat(app): 添加应用入口文件和配置文件&#10;&#10;- 新增 index.tsx 作为应用的主入口文件&#10;- 新增 index.config.ts 用于应用的配置管理">
<option name="closed" value="true" />
<created>1782804461646</created>
<option name="number" value="00034" />
<option name="presentableId" value="LOCAL-00034" />
<option name="project" value="LOCAL" />
<updated>1782804461646</updated>
</task>
<task id="LOCAL-00035" summary="fix(tailwind): 更新配置以兼容微信小程序&#10;&#10;- 启用 autoprefixer 并新增 postcss-nested 插件支持嵌套语法&#10;- 扩展主题颜色,添加 primary 色系&#10;- 更新 content 路径包含 public/index.html&#10;- 禁用 preflight 以移除默认样式重置&#10;- 移除多数 corePlugins 禁用项,保留 preflight 禁用,简化兼容性配置">
<option name="closed" value="true" />
<created>1782805513768</created>
<option name="number" value="00035" />
<option name="presentableId" value="LOCAL-00035" />
<option name="project" value="LOCAL" />
<updated>1782805513768</updated>
</task>
<task id="LOCAL-00036" summary="feat(postcss): 添加插件移除微信小程序不兼容Tailwind规则&#10;&#10;- 实现 postcss-remove-wxss-incompatible 插件&#10;- 移除反斜杠转义的重要性修饰符类选择器(.\!xxx&#10;- 删除依赖 :not 和兄弟选择器的 .space-[x|y]-* 规则&#10;- 删除依赖 :not 和兄弟选择器的 .divide-[x|y]-* 规则&#10;- 解决微信小程序 WXSS 不支持的 CSS 特性问题">
<option name="closed" value="true" />
<created>1782808735147</created>
<option name="number" value="00036" />
<option name="presentableId" value="LOCAL-00036" />
<option name="project" value="LOCAL" />
<updated>1782808735147</updated>
</task>
<task id="LOCAL-00037" summary="feat(postcss): 添加插件移除微信小程序不兼容Tailwind规则&#10;&#10;- 实现 postcss-remove-wxss-incompatible 插件&#10;- 移除反斜杠转义的重要性修饰符类选择器(.\!xxx&#10;- 删除依赖 :not 和兄弟选择器的 .space-[x|y]-* 规则&#10;- 删除依赖 :not 和兄弟选择器的 .divide-[x|y]-* 规则&#10;- 解决微信小程序 WXSS 不支持的 CSS 特性问题">
<option name="closed" value="true" />
<created>1782808737652</created>
<option name="number" value="00037" />
<option name="presentableId" value="LOCAL-00037" />
<option name="project" value="LOCAL" />
<updated>1782808737652</updated>
</task>
<task id="LOCAL-00038" summary="feat(postcss): 添加插件移除微信小程序不兼容Tailwind规则&#10;&#10;- 实现 postcss-remove-wxss-incompatible 插件&#10;- 移除反斜杠转义的重要性修饰符类选择器(.\!xxx&#10;- 删除依赖 :not 和兄弟选择器的 .space-[x|y]-* 规则&#10;- 删除依赖 :not 和兄弟选择器的 .divide-[x|y]-* 规则&#10;- 解决微信小程序 WXSS 不支持的 CSS 特性问题">
<option name="closed" value="true" />
<created>1782808741979</created>
<option name="number" value="00038" />
<option name="presentableId" value="LOCAL-00038" />
<option name="project" value="LOCAL" />
<updated>1782808741979</updated>
</task>
<task id="LOCAL-00039" summary="fix(pay): 优化订阅号获取逻辑并调整支付组件样式&#10;&#10;- 优先从小程序码 scene 参数读取 subscriptionNo提升参数兼容性&#10;- 对 scene 参数进行解码,避免编码引起的问题&#10;- 移除支付组件价格显示处的固定颜色设置,增强样式灵活性">
<option name="closed" value="true" />
<created>1782810191833</created>
<option name="number" value="00039" />
<option name="presentableId" value="LOCAL-00039" />
<option name="project" value="LOCAL" />
<updated>1782810191833</updated>
</task>
<task id="LOCAL-00040" summary="fix(utils): 优化小程序端复制文本功能体验&#10;&#10;- 小程序端直接调用原生 wx.setClipboardData避免 Taro Promise 封装问题&#10;- 避免微信小程序重复显示复制成功提示和误报复制失败&#10;- 失败时仅在小程序端输出错误日志,非小程序端显示提示&#10;- 修改首页外链跳转逻辑,支持相对路径跳转,小程序内外链复制提示提升用户体验&#10;- 更新项目内剪切板使用规范文档,说明复制行为调整及符合相应规范要求">
<option name="closed" value="true" />
<created>1782814230613</created>
<option name="number" value="00040" />
<option name="presentableId" value="LOCAL-00040" />
<option name="project" value="LOCAL" />
<updated>1782814230613</updated>
</task>
<task id="LOCAL-00041" summary="fix(utils): 优化小程序端复制文本功能体验&#10;&#10;- 小程序端直接调用原生 wx.setClipboardData避免 Taro Promise 封装问题&#10;- 避免微信小程序重复显示复制成功提示和误报复制失败&#10;- 失败时仅在小程序端输出错误日志,非小程序端显示提示&#10;- 修改首页外链跳转逻辑,支持相对路径跳转,小程序内外链复制提示提升用户体验&#10;- 更新项目内剪切板使用规范文档,说明复制行为调整及符合相应规范要求">
<option name="closed" value="true" />
<created>1782814693982</created>
<option name="number" value="00041" />
<option name="presentableId" value="LOCAL-00041" />
<option name="project" value="LOCAL" />
<updated>1782814693982</updated>
</task>
<task id="LOCAL-00042" summary="fix(index): 优化外链提示及删除复制咨询模板功能&#10;&#10;- 替换小程序内外链打开方式提示为弹窗提醒用户手动复制&#10;- 删除复制咨询模板功能及相关按钮&#10;- 修改联系我们文案,突出直接电话沟通或需求反馈&#10;- 移除无用导入的复制文本工具函数copyText">
<option name="closed" value="true" />
<created>1782814719111</created>
<option name="number" value="00042" />
<option name="presentableId" value="LOCAL-00042" />
<option name="project" value="LOCAL" />
<updated>1782814719111</updated>
</task>
<task id="LOCAL-00043" summary="feat(utils): 优化请求函数URL拼接逻辑&#10;&#10;- 在request函数中将请求拦截改为先拼接完整URL&#10;- 支持相对路径自动补全baseUrl&#10;- 删除原有请求拦截中url未处理的问题">
<option name="closed" value="true" />
<created>1782879460607</created>
<option name="number" value="00043" />
<option name="presentableId" value="LOCAL-00043" />
<option name="project" value="LOCAL" />
<updated>1782879460607</updated>
</task>
<task id="LOCAL-00044" summary="feat(utils): 优化请求函数URL拼接逻辑&#10;&#10;- 在request函数中将请求拦截改为先拼接完整URL&#10;- 支持相对路径自动补全baseUrl&#10;- 删除原有请求拦截中url未处理的问题">
<option name="closed" value="true" />
<created>1782881600013</created>
<option name="number" value="00044" />
<option name="presentableId" value="LOCAL-00044" />
<option name="project" value="LOCAL" />
<updated>1782881600013</updated>
</task>
<task id="LOCAL-00045" summary="feat(utils): 优化请求函数URL拼接逻辑&#10;&#10;- 在request函数中将请求拦截改为先拼接完整URL&#10;- 支持相对路径自动补全baseUrl&#10;- 删除原有请求拦截中url未处理的问题">
<option name="closed" value="true" />
<created>1782881602732</created>
<option name="number" value="00045" />
<option name="presentableId" value="LOCAL-00045" />
<option name="project" value="LOCAL" />
<updated>1782881602732</updated>
</task>
<task id="LOCAL-00046" summary="feat(utils): 优化请求函数URL拼接逻辑&#10;&#10;- 在request函数中将请求拦截改为先拼接完整URL&#10;- 支持相对路径自动补全baseUrl&#10;- 删除原有请求拦截中url未处理的问题">
<option name="closed" value="true" />
<created>1782881620199</created>
<option name="number" value="00046" />
<option name="presentableId" value="LOCAL-00046" />
<option name="project" value="LOCAL" />
<updated>1782881620199</updated>
</task>
<task id="LOCAL-00047" summary="feat(utils): 优化请求函数URL拼接逻辑&#10;&#10;- 在request函数中将请求拦截改为先拼接完整URL&#10;- 支持相对路径自动补全baseUrl&#10;- 删除原有请求拦截中url未处理的问题">
<option name="closed" value="true" />
<created>1782881623335</created>
<option name="number" value="00047" />
<option name="presentableId" value="LOCAL-00047" />
<option name="project" value="LOCAL" />
<updated>1782881623335</updated>
</task>
<task id="LOCAL-00048" summary="feat(utils): 优化请求函数URL拼接逻辑&#10;&#10;- 在request函数中将请求拦截改为先拼接完整URL&#10;- 支持相对路径自动补全baseUrl&#10;- 删除原有请求拦截中url未处理的问题">
<option name="closed" value="true" />
<created>1782881646712</created>
<option name="number" value="00048" />
<option name="presentableId" value="LOCAL-00048" />
<option name="project" value="LOCAL" />
<updated>1782881646712</updated>
</task>
<task id="LOCAL-00049" summary="docs(schedule): 添加2026年7月1日日程文件&#10;&#10;- 创建新的日程文档文件 2026-07-01.md&#10;- 文件内容待后续补充和更新">
<option name="closed" value="true" />
<created>1782899810526</created>
<option name="number" value="00049" />
<option name="presentableId" value="LOCAL-00049" />
<option name="project" value="LOCAL" />
<updated>1782899810526</updated>
</task>
<task id="LOCAL-00050" summary="docs(schedule): 添加2026年7月1日日程文件&#10;&#10;- 创建新的日程文档文件 2026-07-01.md&#10;- 文件内容待后续补充和更新">
<option name="closed" value="true" />
<created>1782899812498</created>
<option name="number" value="00050" />
<option name="presentableId" value="LOCAL-00050" />
<option name="project" value="LOCAL" />
<updated>1782899812498</updated>
</task>
<task id="LOCAL-00051" summary="feat(pay): 优化小程序支付流程并增强日志调试&#10;&#10;- 更新 wx-login 接口以返回完整 LoginResult包括 access_token 和 user 对象&#10;- 支付页面新增大量日志,详尽打印参数、请求和响应信息&#10;- 优化获取订阅详情流程,支持 returnRaw 返回完整响应用于调试&#10;- 支付流程新增步骤,先通过 code 获取 openid 并缓存,再尝试用 openid 自动登录&#10;- 增加自动登录失败交互,提示未注册用户先登录&#10;- 支付相关请求均使用 returnRaw 方便错误排查&#10;- request 请求模块添加统一请求和响应日志,增强调试能力&#10;- request 认证错误和业务错误时加入详细日志输出">
<option name="closed" value="true" />
<created>1782979300991</created>
<option name="number" value="00051" />
<option name="presentableId" value="LOCAL-00051" />
<option name="project" value="LOCAL" />
<updated>1782979300991</updated>
</task>
<task id="LOCAL-00052" summary="feat(pay): 支付成功后自动跳转到已购产品页面&#10;&#10;- 支付成功后显示成功提示&#10;- 延迟1.5秒自动跳转到已购产品页面&#10;- 处理跳转失败时回退到用户首页&#10;- 优化用户支付完成后的使用体验">
<option name="closed" value="true" />
<created>1783003209100</created>
<option name="number" value="00052" />
<option name="presentableId" value="LOCAL-00052" />
<option name="project" value="LOCAL" />
<updated>1783003209100</updated>
</task>
<task id="LOCAL-00053" summary="feat(pay-bak): 新增小程序支付页面及相关配置&#10;&#10;- 新增确认支付页面配置,设置导航栏标题和样式&#10;- 实现小程序支付页完整组件逻辑包括加载订单、发起JSAPI支付等&#10;- 支持通过 scene 或 subscriptionNo 获取订单参数&#10;- 完善支付流程接口请求及错误处理,支持自动登录和支付确认&#10;- 增加支付成功、支付中、支付失败、取消等状态页面展示&#10;- 支持支付成功后跳转已购产品页或用户页&#10;- 提供取消支付返回逻辑和界面展示&#10;- 细化支付金额显示和提示用户支付后可使用应用功能">
<option name="closed" value="true" />
<created>1784131564427</created>
<option name="number" value="00053" />
<option name="presentableId" value="LOCAL-00053" />
<option name="project" value="LOCAL" />
<updated>1784131564427</updated>
</task>
<option name="localTasksCounter" value="54" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
<option name="CHECK_NEW_TODO" value="false" />
<MESSAGE value="refactor(api): 移除未使用的配置接口及相关Hook&#10;&#10;- 从cmsWebsiteField接口中删除configWebsiteField方法&#10;- 删除useConfig自定义Hook及其引用&#10;- 更新about页面去除对config对象和useConfig的使用&#10;- 修正invite模块请求URL统一加上/api前缀" />
<MESSAGE value="fix(invite): 修正邀请接口路径以支持小程序专用前缀&#10;&#10;- 将请求邀请信息接口路径改为使用 /api/_app 前缀,确保小程序免登录访问&#10;- 修改接受邀请接口路径,统一使用小程序专用 API 域名和前缀&#10;- 更新邀请相关接口注释,明确小程序专用接口前缀含义&#10;- 在专家历史数据中添加高级开发工程师 Will 的条目并更新时间戳" />
<MESSAGE value="fix(passport): 添加邀请接受接口调试日志&#10;&#10;- 在接受邀请请求前打印token和请求URL、参数&#10;- 在请求响应后输出接口响应及返回数据&#10;- 在调用失败时打印错误信息及异常日志&#10;- 保持请求流程和状态管理不变,增强调试能力" />
<MESSAGE value="fix(passport): 优化邀请码接受失败的用户提示和处理&#10;&#10;- 针对“用户不存在”、“用户创建失败”及“请先登录”提示,改为弹窗提示需登录&#10;- 在弹窗中增加“去登录”按钮点击后跳转到登录页面并携带重定向token参数&#10;- 其他错误仍使用原Toast提示方式展示错误信息&#10;- 保留错误日志打印,便于排查异常情况" />
<MESSAGE value="feat(passport-invite): 优化新用户扫码邀请加入流程&#10;&#10;- 扫码进入邀请页面时保存邀请 token 到本地存储&#10;- 新增登录状态检测,未登录用户点击快速加入时保存邀请信息并跳转登录页&#10;- 登录成功后返回邀请页自动执行加入应用操作,提升用户体验&#10;- 支持已登录用户直接加入应用,简化流程&#10;- 增加清理 pending 邀请数据的方法,防止数据残留&#10;- 监听页面显示事件,处理登录返回后自动操作&#10;- 调整接口请求逻辑,确保携带最新的邀请和授权数据&#10;- 更新项目配置,注册邀请页面路径信息" />
<MESSAGE value="feat(passport): 重写登录与邀请加入流程,支持微信手机号一键登录&#10;&#10;- 完全重写 passport/login.tsx实现微信手机号一键登录功能&#10;- 支持登录页面携带 redirect 参数,登录后自动跳转回原页面&#10;- 登录成功后自动处理邀请加入应用,支持邀请关系绑定&#10;- 重写 passport/invite/index.tsx实现扫码邀请加入应用完整流程&#10;- 支持调用 wx.login 获取 code使用 loginByOpenId 判断注册状态&#10;- 未注册用户自动跳转登录页完成微信手机号登录再加入应用&#10;- 已登录用户直接执行加入应用操作,加入接口支持 Authorization 头&#10;-" />
<MESSAGE value="feat(invite): 重构邀请加入流程,实现已登录用户免授权直接加入&#10;&#10;- 完全重写邀请页逻辑,区分已登录与未注册用户按钮显示&#10;- 已登录用户显示“确认加入”按钮,点击用 wx.login 获取 code 加入&#10;- 未注册用户显示“微信手机号快速加入”按钮,授权手机号后完成注册登录再加入&#10;- 移除跳转登录页面逻辑,所有流程在邀请页内完成&#10;- 加入接口统一使用 Authorization 头携带 token确保身份双重验证&#10;- 优化背景、粒子和扫描线效果,提升界面视觉体验&#10;- 增加错误处理提示,加入失败时显示详细原因并可返回首页&#10;- 协议勾选仅在未注册用户显示,确保合规授权流程" />
<MESSAGE value="feat(passport): 优化已登录用户加入时协议勾选逻辑&#10;&#10;- 已登录用户点击「确认加入」时不再强制勾选协议&#10;- 移除 handleConfirmJoin 中对协议勾选的检查&#10;- 未注册用户仍需勾选协议后才能授权手机号&#10;- 确保登录状态异常时有提示信息显示" />
<MESSAGE value="feat(invite): 支持已登录用户直接加入应用&#10;&#10;- 后端accept接口code参数改为可选支持通过Authorization头识别登录用户&#10;- 已登录用户加入时不再弹手机号授权前端调用新增的doJoinAppForLoggedInUser方法&#10;- 未注册用户仍通过手机号授权码code加入调用doJoinAppForNewUser方法&#10;- 拆分前端加入逻辑新增handleConfirmJoin统一处理已登录加入流程&#10;- 优化按钮交互,已登录状态下按钮变为普通点击,移除协议强制勾选&#10;- 错误处理和状态提示完善,加入成功后自动跳转首页" />
<MESSAGE value="feat(developer): 完成小程序开发者中心和企业控制台改造&#10;&#10;- 设计并实现了开发者中心与企业控制台两大模块&#10;- 按用户角色区分开发者和企业客户,支持多项目类型及成员管理&#10;- 新增项目管理、应用管理、API Key管理及成员邀请等多功能页面&#10;- 实现应用版本发布、消息通知中心、权限审批与开发者申请流程&#10;- 完成CI/CD流水线、运营监控、发票管理、SSO单点登录功能&#10;- 搭建SDK下载中心、工单系统、FAQ系统、数据导入导出等模块&#10;- 优化后端API支持已登录和未注册用户不同加入应用流程&#10;- 前端按钮统一采用微信手机号授权,完善用户授权体验&#10;- 修复多个页面的JSX语法错误及依赖导入问题替换部分组件库&#10;- 增加详细的类型定义文件,提升项目类型安全&#10;- 新增超过55个页面及60个API接口扩展应用功能和服务体系&#10;- 完成全面的样式设计,实现一致的视觉风格和交互体验" />
<MESSAGE value="feat(api-keys): 优化隐私协议同意逻辑及样式&#10;&#10;- 修正api-keys样式导入路径改为developer路径&#10;- 在开发者申请页面增加服务协议和隐私政策勾选框&#10;- 提交时校验协议是否已勾选,未勾选时提示用户&#10;- 优化申请页面协议区域样式及交互&#10;- 在用户验证页面添加隐私政策同意勾选框&#10;- 提交用户验证表单时检查协议同意状态&#10;- 增加打开服务协议和隐私政策的链接跳转&#10;- 更新项目配置增加passport/webview路由配置&#10;- 修复createTicket函数中日期格式正则表达式问题" />
<MESSAGE value="refactor(config): 移除开发者中心和企业控制台的自定义导航样式&#10;&#10;- 删除了开发者中心页面配置中的 navigationStyle: 'custom'&#10;- 删除了企业控制台页面配置中的 navigationStyle: 'custom'&#10;- 简化了页面配置,保持默认导航样式&#10;- 有助于提升页面兼容性和维护性" />
<MESSAGE value="feat(userVerify): 添加阿里云身份证二要素核验功能&#10;&#10;- 在接口层新增 verifyIdCard 接口,实现姓名与身份证号核验&#10;- userVerify 页面提交时增加身份核验逻辑,核验失败阻止提交&#10;- 调用核验接口时显示加载状态,并根据结果提示用户&#10;- 后端依赖 aliyun cloudauth提供实人认证相关服务接口&#10;- 完成基本的错误捕获与用户提示,提升实名认证流程安全性" />
<MESSAGE value="refactor(api): 规范前端API接口地址并统一路径前缀&#10;&#10;- 修正开发者、小程序和企业相关API的基础URL避免重复添加/api前缀&#10;- 统一调整developer、enterprise、invite等模块接口路径保持与后端Controller一致&#10;- 新增权限申请及消息通知相关API并完善相关函数实现&#10;- 规范请求参数传递,移除多余包装,改用直接传递对象方式&#10;- 新增API Key重置、版本发布/回滚等接口支持&#10;&#10;feat(invite): 重构邀请登录流程支持未注册快速加入&#10;&#10;- 完整重写invite页分离已注册用户和未注册用户的按钮显示和交互&#10;- 实现未注册用户微信手机号授权后自动注册登录及自动加入应用&#10;- 已注册用户直接确认加入应用,无需手机号授权弹窗&#10;- 统一使用getPhoneNumber按钮处理两种状态并修复“授权码不能为空”报错&#10;- 前端配合后端改造支持已登录用户可直接通过Authorization头加入应用&#10;&#10;fix(developer): 修复开发者中心应用加载问题&#10;&#10;- 修复只查询创建的应用导致邀请加入的应用不显示的问题&#10;- 同时请求创建应用和参与应用接口,合并并去重应用列表&#10;- 新增pageJoinedApp接口调用及合并逻辑提高应用列表完整性和体验" />
<MESSAGE value="feat(app): 添加应用入口文件和配置文件&#10;&#10;- 新增 index.tsx 作为应用的主入口文件&#10;- 新增 index.config.ts 用于应用的配置管理" />
<MESSAGE value="fix(tailwind): 更新配置以兼容微信小程序&#10;&#10;- 启用 autoprefixer 并新增 postcss-nested 插件支持嵌套语法&#10;- 扩展主题颜色,添加 primary 色系&#10;- 更新 content 路径包含 public/index.html&#10;- 禁用 preflight 以移除默认样式重置&#10;- 移除多数 corePlugins 禁用项,保留 preflight 禁用,简化兼容性配置" />
<MESSAGE value="feat(postcss): 添加插件移除微信小程序不兼容Tailwind规则&#10;&#10;- 实现 postcss-remove-wxss-incompatible 插件&#10;- 移除反斜杠转义的重要性修饰符类选择器(.\!xxx&#10;- 删除依赖 :not 和兄弟选择器的 .space-[x|y]-* 规则&#10;- 删除依赖 :not 和兄弟选择器的 .divide-[x|y]-* 规则&#10;- 解决微信小程序 WXSS 不支持的 CSS 特性问题" />
<MESSAGE value="fix(pay): 优化订阅号获取逻辑并调整支付组件样式&#10;&#10;- 优先从小程序码 scene 参数读取 subscriptionNo提升参数兼容性&#10;- 对 scene 参数进行解码,避免编码引起的问题&#10;- 移除支付组件价格显示处的固定颜色设置,增强样式灵活性" />
<MESSAGE value="fix(utils): 优化小程序端复制文本功能体验&#10;&#10;- 小程序端直接调用原生 wx.setClipboardData避免 Taro Promise 封装问题&#10;- 避免微信小程序重复显示复制成功提示和误报复制失败&#10;- 失败时仅在小程序端输出错误日志,非小程序端显示提示&#10;- 修改首页外链跳转逻辑,支持相对路径跳转,小程序内外链复制提示提升用户体验&#10;- 更新项目内剪切板使用规范文档,说明复制行为调整及符合相应规范要求" />
<MESSAGE value="fix(index): 优化外链提示及删除复制咨询模板功能&#10;&#10;- 替换小程序内外链打开方式提示为弹窗提醒用户手动复制&#10;- 删除复制咨询模板功能及相关按钮&#10;- 修改联系我们文案,突出直接电话沟通或需求反馈&#10;- 移除无用导入的复制文本工具函数copyText" />
<MESSAGE value="feat(utils): 优化请求函数URL拼接逻辑&#10;&#10;- 在request函数中将请求拦截改为先拼接完整URL&#10;- 支持相对路径自动补全baseUrl&#10;- 删除原有请求拦截中url未处理的问题" />
<MESSAGE value="docs(schedule): 添加2026年7月1日日程文件&#10;&#10;- 创建新的日程文档文件 2026-07-01.md&#10;- 文件内容待后续补充和更新" />
<MESSAGE value="feat(pay): 优化小程序支付流程并增强日志调试&#10;&#10;- 更新 wx-login 接口以返回完整 LoginResult包括 access_token 和 user 对象&#10;- 支付页面新增大量日志,详尽打印参数、请求和响应信息&#10;- 优化获取订阅详情流程,支持 returnRaw 返回完整响应用于调试&#10;- 支付流程新增步骤,先通过 code 获取 openid 并缓存,再尝试用 openid 自动登录&#10;- 增加自动登录失败交互,提示未注册用户先登录&#10;- 支付相关请求均使用 returnRaw 方便错误排查&#10;- request 请求模块添加统一请求和响应日志,增强调试能力&#10;- request 认证错误和业务错误时加入详细日志输出" />
<MESSAGE value="feat(pay): 支付成功后自动跳转到已购产品页面&#10;&#10;- 支付成功后显示成功提示&#10;- 延迟1.5秒自动跳转到已购产品页面&#10;- 处理跳转失败时回退到用户首页&#10;- 优化用户支付完成后的使用体验" />
<MESSAGE value="feat(pay-bak): 新增小程序支付页面及相关配置&#10;&#10;- 新增确认支付页面配置,设置导航栏标题和样式&#10;- 实现小程序支付页完整组件逻辑包括加载订单、发起JSAPI支付等&#10;- 支持通过 scene 或 subscriptionNo 获取订单参数&#10;- 完善支付流程接口请求及错误处理,支持自动登录和支付确认&#10;- 增加支付成功、支付中、支付失败、取消等状态页面展示&#10;- 支持支付成功后跳转已购产品页或用户页&#10;- 提供取消支付返回逻辑和界面展示&#10;- 细化支付金额显示和提示用户支付后可使用应用功能" />
<option name="LAST_COMMIT_MESSAGE" value="feat(pay-bak): 新增小程序支付页面及相关配置&#10;&#10;- 新增确认支付页面配置,设置导航栏标题和样式&#10;- 实现小程序支付页完整组件逻辑包括加载订单、发起JSAPI支付等&#10;- 支持通过 scene 或 subscriptionNo 获取订单参数&#10;- 完善支付流程接口请求及错误处理,支持自动登录和支付确认&#10;- 增加支付成功、支付中、支付失败、取消等状态页面展示&#10;- 支持支付成功后跳转已购产品页或用户页&#10;- 提供取消支付返回逻辑和界面展示&#10;- 细化支付金额显示和提示用户支付后可使用应用功能" />
<option name="NON_MODAL_COMMIT_POSTPONE_SLOW_CHECKS" value="false" />
</component>
</project>

View File

@@ -0,0 +1,16 @@
# 2026-07-16 工作日志
## passport 分包化修复
用户把登录/注册相关页面放入 `passport` 分包(`src/app.config.ts` 的 subpackages
排查结论:
- 主包内所有跳转引用(`src/pages/**``src/utils/auth.ts``src/components/QRLoginScanner.tsx` 等)已全部使用 `/passport/xxx` 路径。分包化前后 URL 路径不变,引用代码无需修改。
- passport 内 10 个页面login/forget/setting/agreement/sms-login/register/qr-login/qr-confirm/unified-qr/pay均有 `.tsx` + `.config.ts``@` 别名指向 `src/`,移动目录不影响 import。
修复 `src/app.config.ts` 分包声明(与实际文件对齐):
- 移除 `phone-auth/index``invite/index``webview/index`(文件不存在,且全局无任何跳转引用它们,会导致 Taro 编译报错)
- 补充 `register``src/passport/register.tsx` 存在但未声明)
- 统一引号风格、清理尾随逗号
待确认phone-auth / invite / webview 三个页面是否需要新建(目前无文件、无引用)。

263
README.md Normal file
View File

@@ -0,0 +1,263 @@
# Paopao Taro - 项目框架
基于 Taro 4.0.8 + React 18.3.1 + TypeScript 5.7.2 的跨端开发框架
## 📦 技术栈
### 核心框架
- **Taro**: `4.0.8` - 跨端开发框架
- **React**: `18.3.1` - UI 框架
- **TypeScript**: `5.7.2` - 类型系统
### UI 组件库
- **NutUI React Taro**: `2.7.4` - 京东风格的 Taro React 组件库
- **NutUI Icons**: `^1.0.0` - 图标库
### 样式方案
- **Sass**: `^1.81.0` - CSS 预处理器
- **TailwindCSS**: `3.4.17` - 原子化 CSS 框架
### 状态管理
- **React Hooks** - 内置 Hooks
- **Context API** - 跨组件状态共享
### 工具库
- **Day.js**: `^1.11.13` - 日期处理
- **Crypto-js**: `^4.2.0` - 加密解密
- **React Router DOM**: `^6.28.0` - 路由管理
## 🚀 快速开始
### 安装依赖
```bash
# 使用 npm
npm install
# 使用 yarn
yarn install
# 使用 pnpm
pnpm install
```
### 开发模式
```bash
# 微信小程序
npm run dev:weapp
# H5
npm run dev:h5
# 支付宝小程序
npm run dev:alipay
# 百度小程序
npm run dev:swan
# 字节跳动小程序
npm run dev:tt
# QQ 小程序
npm run dev:qq
```
### 生产构建
```bash
# 微信小程序
npm run build:weapp
# H5
npm run build:h5
# 其他平台类似
npm run build:[platform]
```
## 📁 项目结构
```
shop-taro/
├── config/ # Taro 配置文件
│ ├── index.ts # 主配置
│ ├── dev.ts # 开发配置
│ └── prod.ts # 生产配置
├── src/ # 源代码
│ ├── app.config.ts # 应用配置页面路由、tabBar等
│ ├── app.tsx # 应用入口
│ ├── app.scss # 全局样式
│ ├── pages/ # 页面目录
│ │ ├── index/ # 首页
│ │ │ ├── index.tsx
│ │ │ ├── index.scss
│ │ │ └── index.config.ts
│ │ └── home/ # 个人中心页
│ │ ├── home.tsx
│ │ ├── home.scss
│ │ └── home.config.ts
│ ├── components/ # 自定义组件
│ ├── contexts/ # Context API
│ │ └── AppContext.tsx # 应用上下文
│ ├── hooks/ # 自定义 Hooks
│ │ └── useAppContext.ts
│ ├── utils/ # 工具函数
│ │ └── index.ts # 常用工具(日期、加密、防抖节流等)
│ ├── types/ # TypeScript 类型定义
│ │ └── global.d.ts # 全局类型声明
│ ├── styles/ # 样式文件
│ └── assets/ # 静态资源
│ └── tabbar/ # tabBar 图标
├── package.json # 项目依赖
├── tsconfig.json # TypeScript 配置
├── tailwind.config.js # TailwindCSS 配置
├── postcss.config.js # PostCSS 配置
├── project.config.json # 小程序项目配置
└── README.md # 项目说明
```
## ✨ 特性
### 1. 主题切换
- 支持浅色/深色模式切换
- 使用 Context API 管理主题状态
- 暗黑模式适配
### 2. NutUI 组件库
- 已集成 @nutui/nutui-react-taro@2.7.4
- 支持按需引入
- 中文国际化配置
### 3. TailwindCSS 集成
- 支持原子化 CSS 编写
- 暗黑模式支持dark mode
- 自定义主题色配置
### 4. 工具函数封装
- **日期处理**: 基于 Day.js 的格式化
- **加密解密**: MD5、AES 加密
- **性能优化**: 防抖、节流函数
- **数据操作**: 深拷贝等工具
### 5. TypeScript 支持
- 完整的类型定义
- 路径别名配置 `@/*`
- 严格模式开启
## 🎨 代码示例
### 使用 NutUI 组件
```tsx
import { Button, Cell, CellGroup } from '@nutui/nutui-react-taro'
export default function MyPage() {
return (
<CellGroup>
<Cell title="标题" description="描述" />
<Button type="primary" block>
提交
</Button>
</CellGroup>
)
}
```
### 使用 TailwindCSS
```tsx
<View className="p-4 bg-white dark:bg-gray-800">
<Text className="text-lg font-bold text-gray-800 dark:text-white">
暗黑模式适配文本
</Text>
</View>
```
### 使用 Context 管理状态
```tsx
import { useAppContext } from '@/hooks/useAppContext'
export default function MyPage() {
const { theme, toggleTheme } = useAppContext()
return (
<Button onClick={toggleTheme}>
当前主题: {theme}
</Button>
)
}
```
### 使用工具函数
```tsx
import { formatDate, md5, debounce } from '@/utils'
// 日期格式化
const dateStr = formatDate(new Date())
// MD5 加密
const encrypted = md5('hello world')
// 防抖
const handleSearch = debounce((keyword) => {
console.log(keyword)
}, 500)
```
## 📝 开发规范
### 文件命名
- 页面目录: `kebab-case` (如 `user-profile/`)
- 组件文件: `PascalCase` (如 `UserProfile.tsx`)
- 工具文件: `camelCase` (如 `formatDate.ts`)
### 代码风格
- 使用 ESLint + @typescript-eslint 进行代码检查
- 使用 2 空格缩进
- 分号结尾
- 单引号优先
### 提交规范
```
feat: 新功能
fix: 修复 bug
docs: 文档更新
style: 代码格式调整
refactor: 重构
test: 测试相关
chore: 构建/工具配置
```
## 🔧 常见问题
### 1. TailwindCSS 样式不生效?
检查 `postcss.config.js` 配置,确保已安装 `postcss-nested`
### 2. NutUI 组件样式丢失?
确保在 `app.scss` 中引入了 NutUI 样式:
```scss
@import '@nutui/nutui-react-taro/dist/styles/vitamin.css';
```
### 3. TypeScript 路径别名报错?
检查 `tsconfig.json``paths` 配置,并确保 IDE 正确识别。
## 📚 相关文档
- [Taro 官方文档](https://taro-docs.jd.com/)
- [React 官方文档](https://react.dev/)
- [NutUI React 文档](https://nutui.jd.com/react-taro/)
- [TailwindCSS 文档](https://tailwindcss.com/docs)
- [TypeScript 文档](https://www.typescriptlang.org/docs/)
## 📄 License
MIT
---
**构建时间**: 2026-05-10
**作者**: Senior Developer

11
babel.config.js Normal file
View File

@@ -0,0 +1,11 @@
module.exports = {
"presets": [
["taro", {
"framework": "react",
"ts": true
}]
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}

7
config/app.ts Normal file
View File

@@ -0,0 +1,7 @@
import { API_BASE_URL, SERVER_API_URL } from './env'
export const TenantId = '5'
export const TenantName = '威硕开发助手'
export const BaseUrl = API_BASE_URL
export const ServerBaseUrl = SERVER_API_URL
export const Version = 'v3.0.0'

17
config/dev.ts Normal file
View File

@@ -0,0 +1,17 @@
export default {
env: {
NODE_ENV: '"development"'
},
defineConstants: {
__DEV__: JSON.stringify(true)
},
mini: {},
h5: {
devServer: {
host: 'localhost',
port: 10086,
hot: true,
open: false
}
}
}

28
config/env.js Normal file
View File

@@ -0,0 +1,28 @@
const CURRENT_ENV = process.env.NODE_ENV === 'production' ? 'production' : 'development'
export const ENV_CONFIG = {
development: {
API_BASE_URL: 'https://shop-api.websoft.top/api',
SERVER_API_URL: 'https://server.websoft.top/api',
APP_NAME: '威硕谱软件',
DEBUG: 'true',
},
test: {
API_BASE_URL: 'https://shop-api.websoft.top/api',
SERVER_API_URL: 'https://server.websoft.top/api',
APP_NAME: '威硕谱软件',
DEBUG: 'true',
},
production: {
API_BASE_URL: 'https://shop-api.websoft.top/api',
SERVER_API_URL: 'https://server.websoft.top/api',
APP_NAME: '威硕谱软件',
DEBUG: 'false',
},
}
export function getEnvConfig() {
return ENV_CONFIG[CURRENT_ENV] || ENV_CONFIG.development
}
export const { API_BASE_URL, SERVER_API_URL, APP_NAME, DEBUG } = getEnvConfig()

120
config/index.ts Normal file
View File

@@ -0,0 +1,120 @@
import { defineConfig, type UserConfigExport } from '@tarojs/cli'
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'
import { UnifiedWebpackPluginV5 } from 'weapp-tailwindcss/webpack'
import devConfig from './dev'
import prodConfig from './prod'
import path from 'path'
import { getEnvConfig } from './env.js'
// https://taro-docs.jd.com/docs/next/config
export default defineConfig<'webpack5'>(async (merge, { mode }) => {
const baseConfig: UserConfigExport<'webpack5'> = {
// 项目配置
projectName: 'shop-taro',
date: '2026-5-10',
designWidth: 750,
deviceRatio: {
640: 2.34 / 2,
750: 1,
828: 1.81 / 2
},
sourceRoot: 'src',
outputRoot: 'dist',
plugins: [
'@tarojs/plugin-platform-weapp',
'@tarojs/plugin-platform-h5'
],
// 编译配置
defineConstants: {
API_BASE_URL: JSON.stringify(getEnvConfig().API_BASE_URL),
SERVER_API_URL: JSON.stringify(getEnvConfig().SERVER_API_URL),
APP_NAME: JSON.stringify(getEnvConfig().APP_NAME),
DEBUG: JSON.stringify(getEnvConfig().DEBUG),
},
copy: {
patterns: [],
options: {}
},
framework: 'react',
compiler: {
type: 'webpack5',
prebundle: {
enable: false
}
},
// 开启持久化缓存 - 有效提升二次编译速度
cache: {
enable: false,
type: 'filesystem',
cacheDirectory: path.resolve(__dirname, '../.webpack-cache'),
buildDependencies: {
config: [__filename]
}
},
// 小程序配置
mini: {
postcss: {
pxtransform: {
enable: true,
config: {}
},
url: {
enable: true,
config: {
limit: 1024
}
},
cssModules: {
enable: false,
config: {
namingPattern: 'module',
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
},
webpackChain(chain) {
chain.resolve.plugin('tsconfig-paths').use(TsconfigPathsPlugin)
// weapp-tailwindcss: 自动处理 TailwindCSS 与 WXSS 的兼容性
chain.merge({
plugin: {
'weapp-tailwindcss': {
plugin: UnifiedWebpackPluginV5,
args: [{
appType: 'taro',
rem2rpx: true,
}]
}
}
})
}
},
// H5 配置
h5: {
publicPath: '/',
staticDirectory: 'static',
postcss: {
autoprefixer: {
enable: true
},
cssModules: {
enable: false,
config: {
namingPattern: 'module',
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
},
webpackChain(chain) {
chain.resolve.plugin('tsconfig-paths').use(TsconfigPathsPlugin)
}
},
}
if (mode === 'development') {
return merge({}, baseConfig, devConfig)
}
return merge({}, baseConfig, prodConfig)
})

12
config/prod.ts Normal file
View File

@@ -0,0 +1,12 @@
export default {
env: {
NODE_ENV: '"production"'
},
defineConstants: {
__DEV__: JSON.stringify(false)
},
mini: {
compressTemplate: true
},
h5: {}
}

316
models.json Normal file
View File

@@ -0,0 +1,316 @@
{
"models": [
{
"id": "auto",
"name": "AuTo",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "deepseek-v4-pro",
"name": "Deepseek-v4-pro",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 1000000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "deepseek-v4-flash",
"name": "Deepseek-v4-flash",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 1000000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "deepseek-v3-2-volc",
"name": "Deepseek-v3-2-volc",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "deepseek-v3-1",
"name": "Deepseek-v3-1",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "deepseek-v3-0324",
"name": "Deepseek-v3-0324",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "deepseek-r1",
"name": "Deepseek-r1",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "glm-5.2",
"name": "GLM-5.2",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 1000000,
"maxOutputTokens": 128000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "glm-5.1",
"name": "GLM-5.1",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 200000,
"maxOutputTokens": 128000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "glm-5.0",
"name": "GLM-5.0",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 200000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "glm-5.0-turbo",
"name": "GLM-5.0-Turbo",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 200000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "glm-5v-turbo",
"name": "GLM-5v-Turbo",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 200000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "glm-4.7",
"name": "GLM-4.7",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "glm-4.6",
"name": "GLM-4.6",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "minimax-m3",
"name": "Minimax-M3",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 1000000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "minimax-m2.7",
"name": "Minimax-M2.7",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "minimax-m2.5",
"name": "Minimax-M2.5",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "kimi-k2.7-code",
"name": "Kimi-K2.7-Code",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 256000,
"maxOutputTokens": 20000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "kimi-k2.6",
"name": "Kimi-K2.6",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 256000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "kimi-k2.5",
"name": "Kimi-K2.5",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 256000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "hy3-preview",
"name": "HY-3-Preview",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 200000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "hy3",
"name": "HY-3",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 256000,
"maxOutputTokens": 192000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "hunyuan-chat",
"name": "HY-Chat",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 128000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
},
{
"id": "hunyuan-2.0-thinking",
"name": "HY-2.0-Thinking",
"vendor": "Custom",
"url": "https://api.getaigate.com/v1/chat/completions",
"apiKey": "sk-aigate-2335f1670e169eb855c88f6ed58862cb",
"maxInputTokens": 200000,
"maxOutputTokens": 32000,
"supportsToolCall": true,
"supportsImages": true,
"supportsReasoning": true,
"useCustomProtocol": false
}
]
}

90
package.json Normal file
View File

@@ -0,0 +1,90 @@
{
"name": "websopy-taro",
"version": "1.0.0",
"private": true,
"description": "Taro + React + TypeScript 项目框架",
"browserslist": [
"last 3 versions",
"Android >= 4.1",
"ios >= 8"
],
"scripts": {
"build:weapp": "taro build --type weapp",
"build:swan": "taro build --type swan",
"build:alipay": "taro build --type alipay",
"build:tt": "taro build --type tt",
"build:h5": "taro build --type h5",
"build:rn": "taro build --type rn",
"build:qq": "taro build --type qq",
"build:jd": "taro build --type jd",
"build:quickapp": "taro build --type quickapp",
"dev:weapp": "npm run build:weapp -- --watch",
"dev:swan": "npm run build:swan -- --watch",
"dev:alipay": "npm run build:alipay -- --watch",
"dev:tt": "npm run build:tt -- --watch",
"dev:h5": "npm run build:h5 -- --watch",
"dev:rn": "npm run build:rn -- --watch",
"dev:qq": "npm run build:qq -- --watch",
"dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch",
"lint": "eslint src --fix --ext .ts,.tsx",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@nutui/icons-react-taro": "^2.0.1",
"@nutui/nutui-biz": "1.0.0-beta.2",
"@nutui/nutui-react": "^3.0.16",
"@nutui/nutui-react-taro": "2.7.4",
"@tarojs/components": "4.1.11",
"@tarojs/plugin-framework-react": "4.1.11",
"@tarojs/plugin-platform-h5": "4.0.8",
"@tarojs/plugin-platform-weapp": "4.1.11",
"@tarojs/react": "4.1.11",
"@tarojs/runtime": "4.1.11",
"@tarojs/shared": "4.1.11",
"@tarojs/taro": "4.1.11",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"echarts-taro3-react": "^1.0.13",
"js-base64": "^3.7.7",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-markdown": "^10.1.0",
"react-router-dom": "^7.1.1",
"weapp-qrcode": "^1.0.0"
},
"devDependencies": {
"@babel/core": "^7.26.0",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/preset-react": "^7.26.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@tarojs/cli": "4.1.11",
"@tarojs/taro-loader": "4.1.11",
"@tarojs/webpack5-runner": "4.1.11",
"@types/node": "^18.19.68",
"@types/react": "^18.3.12",
"@types/webpack-env": "^1.18.5",
"@typescript-eslint/eslint-plugin": "^8.15.0",
"@typescript-eslint/parser": "^8.15.0",
"autoprefixer": "^10.4.20",
"babel-preset-taro": "4.0.8",
"eslint": "^8.56.0",
"eslint-config-taro": "4.0.8",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^4.6.2",
"mysql2": "^3.22.3",
"postcss": "^8.4.49",
"react-refresh": "^0.14.0",
"stylelint": "^14.16.1",
"tailwindcss": "3.4.17",
"ts-node": "^10.9.2",
"tsconfig-paths-webpack-plugin": "^4.2.0",
"typescript": "5.7.2",
"weapp-tailwindcss": "^4.12.0",
"webpack": "5.78.0"
},
"engines": {
"node": ">=18"
}
}

18401
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

7
postcss.config.js Normal file
View File

@@ -0,0 +1,7 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
'postcss-nested': {}
}
}

55
project.config.json Normal file
View File

@@ -0,0 +1,55 @@
{
"description": "websopy-taro 项目配置",
"setting": {
"urlCheck": false,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": true,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": true,
"lazyloadPlaceholderEnable": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"useApiHostProcess": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useIsolateContext": true,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"disableUseStrict": false,
"minifyWXML": true,
"showES6CompileOption": false,
"useCompilerPlugins": false,
"compileWorklet": false,
"localPlugins": false,
"condition": false,
"swc": false,
"disableSWC": true
},
"compileType": "miniprogram",
"appid": "wx541db955e7a62709",
"projectname": "威硕谱软件",
"condition": {},
"simulatorPluginLibVersion": {},
"packOptions": {
"ignore": [],
"include": []
},
"editorSetting": {}
}

View File

@@ -0,0 +1,23 @@
{
"libVersion": "3.16.1",
"projectname": "websopy-taro",
"condition": {},
"setting": {
"urlCheck": false,
"coverView": true,
"lazyloadPlaceholderEnable": false,
"skylineRenderEnable": false,
"preloadBackgroundData": false,
"autoAudits": false,
"useApiHook": true,
"showShadowRootInWxmlPanel": true,
"useStaticServer": false,
"useLanDebug": false,
"showES6CompileOption": false,
"compileHotReLoad": true,
"checkInvalidKey": true,
"ignoreDevUnusedFiles": true,
"bigPackageSizeSupport": false,
"useIsolateContext": true
}
}

115
src/api/cms/cmsAd/index.ts Normal file
View File

@@ -0,0 +1,115 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsAd, CmsAdParam } from './model';
/**
* 分页查询广告位
*/
export async function pageCmsAd(params: CmsAdParam) {
const res = await request.get<ApiResult<PageResult<CmsAd>>>(
'/cms/cms-ad/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询广告位列表
*/
export async function listCmsAd(params?: CmsAdParam) {
const res = await request.get<ApiResult<CmsAd[]>>(
'/cms/cms-ad',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加广告位
*/
export async function addCmsAd(data: CmsAd) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-ad',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改广告位
*/
export async function updateCmsAd(data: CmsAd) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-ad',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除广告位
*/
export async function removeCmsAd(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-ad/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除广告位
*/
export async function removeBatchCmsAd(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-ad/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询广告位
*/
export async function getCmsAd(id: number) {
const res = await request.get<ApiResult<CmsAd>>(
'/cms/cms-ad/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据code查询广告位
*/
export async function getCmsAdByCode(code: string) {
const res = await request.get<ApiResult<CmsAd>>(
'/cms/cms-ad/getByCode/' + code
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,60 @@
import type { PageParam } from '@/api';
/**
* 广告位
*/
export interface CmsAd {
// ID
adId?: number;
// 页面ID
designId?: number;
// 广告类型
adType?: string;
// 广告类型
type?: string;
// 广告位名称
name?: string;
// 宽
width?: string;
// 高
height?: string;
// 广告图片
images?: string;
// 图片列表
imageList?: any[];
// 路由/链接地址
path?: string;
// 用户ID
userId?: number;
// 页面ID
pageId?: number;
// 页面名称
pageName?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
merchantId?: number;
// 图片数组
imgArr?: any[];
}
/**
* 广告位搜索条件
*/
export interface CmsAdParam extends PageParam {
adId?: number;
adType?: string;
pageId?: number;
pageName?: string;
status?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsAdRecord, CmsAdRecordParam } from './model';
/**
* 分页查询广告图片
*/
export async function pageCmsAdRecord(params: CmsAdRecordParam) {
const res = await request.get<ApiResult<PageResult<CmsAdRecord>>>(
'/cms/cms-ad-record/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询广告图片列表
*/
export async function listCmsAdRecord(params?: CmsAdRecordParam) {
const res = await request.get<ApiResult<CmsAdRecord[]>>(
'/cms/cms-ad-record',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加广告图片
*/
export async function addCmsAdRecord(data: CmsAdRecord) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-ad-record',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改广告图片
*/
export async function updateCmsAdRecord(data: CmsAdRecord) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-ad-record',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除广告图片
*/
export async function removeCmsAdRecord(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-ad-record/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除广告图片
*/
export async function removeBatchCmsAdRecord(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-ad-record/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询广告图片
*/
export async function getCmsAdRecord(id: number) {
const res = await request.get<ApiResult<CmsAdRecord>>(
'/cms/cms-ad-record/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,35 @@
import type { PageParam } from '@/api';
/**
* 广告图片
*/
export interface CmsAdRecord {
// ID
adRecordId?: number;
// 广告标题
title?: string;
// 图片地址
path?: string;
// 链接地址
url?: string;
// 广告位ID
adId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 广告图片搜索条件
*/
export interface CmsAdRecordParam extends PageParam {
adRecordId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,218 @@
import request from '@/utils/request';
import type {ApiResult, PageResult} from '@/api';
import type {CmsArticle, CmsArticleParam} from './model';
/**
* 分页查询文章
*/
export async function pageCmsArticle(params: CmsArticleParam) {
const res = await request.get<ApiResult<PageResult<CmsArticle>>>(
'/cms/cms-article/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询文章列表
*/
export async function listCmsArticle(params?: CmsArticleParam) {
const res = await request.get<ApiResult<CmsArticle[]>>(
'/cms/cms-article',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加文章
*/
export async function addCmsArticle(data: CmsArticle) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-article',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改文章
*/
export async function updateCmsArticle(data: CmsArticle) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-article',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除文章
*/
export async function removeCmsArticle(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除文章
*/
export async function removeBatchCmsArticle(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询文章
*/
export async function getCmsArticle(id: number) {
const res = await request.get<ApiResult<CmsArticle>>(
'/cms/cms-article/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
export async function getCount(params?: CmsArticleParam) {
const res = await request.get<ApiResult<unknown>>('/cms/cms-article/data', {
params
});
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 上一篇
* @param params
*/
export async function getPrevious(params?: CmsArticleParam) {
const res = await request.get<ApiResult<CmsArticle>>(
'/cms/cms-article/getPrevious/' + params?.articleId,
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 下一篇
* @param params
*/
export async function getNext(params?: CmsArticleParam) {
const res = await request.get<ApiResult<CmsArticle>>(
'/cms/cms-article/getNext/' + params?.articleId,
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 验证文章密码
* @param params
*/
export async function checkArticlePassword(params?: CmsArticleParam) {
const res = await request.get<ApiResult<unknown>>(
'/cms/cms-article/checkArticlePassword',
{
params
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
export async function findTags(params?: CmsArticleParam) {
const res = await request.get<ApiResult<CmsArticle[]>>(
'/cms/cms-article/findTags',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
export async function pageTags(params?: CmsArticleParam) {
const res = await request.get<ApiResult<CmsArticle[]>>(
'/cms/cms-article/pageTags',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 按IDS查询文章
* @param params
*/
export async function getByIds(params?: CmsArticleParam) {
const res = await request.get<ApiResult<CmsArticle[]>>(
'/cms/cms-article/getByIds',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据code查询文章
*/
export async function getByCode(code: string) {
const res = await request.get<ApiResult<CmsArticle>>(
'/cms/cms-article/getByCode/' + code
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,132 @@
import type { PageParam } from '@/api/index';
/**
* 文章
*/
export interface CmsArticle {
// 文章ID
articleId?: number;
// 文章标题
title?: string;
// 文章类型 0常规 1视频
type?: number;
// 文章模型
model?: string;
// 文章详情页模板
detail?: string;
// banner图片
banner?: string;
// 列表显示方式(10小图展示 20大图展示)
showType?: number;
// 话题
topic?: string;
// 标签
tags?: any;
// 栏目ID
categoryId?: number;
// 栏目名称
categoryName?: string;
// 封面图
image?: string;
// 价格
price?: number;
startTime?: any;
endTime?: any;
// 缩列图
thumbnail?: string;
// 来源
source?: string;
// 产品概述
overview?: string;
// 虚拟阅读量(仅用作展示)
virtualViews?: number;
// 实际阅读量
actualViews?: number;
// 购买人数
bmUsers?: number;
// 浏览权限(0公开 1会员 2密码)
permission?: number;
// 访问密码
password?: string;
// 确认密码
password2?: string;
// 发布来源客户端 (APP、H5、小程序等)
platform?: string;
// 文章附件
files?: string;
// 视频地址
video?: string;
// 接受的文件类型
accept?: string;
// 经度
longitude?: string;
// 纬度
latitude?: string;
// 所在省份
province?: string;
// 所在城市
city?: string;
// 所在辖区
region?: string;
// 街道地址
address?: string;
// 点赞数
likes?: number;
// pdf地址
pdfUrl?: string;
// 评论数
commentNumbers?: number;
// 提醒谁看
toUsers?: string;
// 文章内容
content?: string;
// 是否推荐
recommend?: number;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0已发布, 1待审核 2已驳回 3违规内容
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
// 父级id
parentId?: number;
nickname?: string;
username?: string;
author?: string;
shopId?: number;
tenantName?: string;
logo?: string;
fileList?: any;
// 编辑器类型
editor?: number;
}
/**
* 文章搜索条件
*/
export interface CmsArticleParam extends PageParam {
articleId?: number;
articleIds?: string;
categoryId?: number;
parentId?: number;
status?: number;
// 是否推荐
recommend?: number;
keywords?: string;
// 验证密码
password?: string;
password2?: string;
tags?: string;
detail?: string;
sceneType?: string;
}

View File

@@ -0,0 +1,108 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleCategory, CmsArticleCategoryParam } from './model';
/**
* 分页查询文章分类表
*/
export async function pageCmsArticleCategory(params: CmsArticleCategoryParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleCategory>>>(
'/cms/cms-article-category/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询文章分类表列表
*/
export async function listCmsArticleCategory(params?: CmsArticleCategoryParam) {
const res = await request.get<ApiResult<CmsArticleCategory[]>>(
'/cms/cms-article-category',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加文章分类表
*/
export async function addCmsArticleCategory(data: CmsArticleCategory) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-article-category',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改文章分类表
*/
export async function updateCmsArticleCategory(data: CmsArticleCategory) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-article-category',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除文章分类表
*/
export async function removeCmsArticleCategory(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-category/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除文章分类表
*/
export async function removeBatchCmsArticleCategory(
data: (number | undefined)[]
) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-category/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询文章分类表
*/
export async function getCmsArticleCategory(id: number) {
const res = await request.get<ApiResult<CmsArticleCategory>>(
'/cms/cms-article-category/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,59 @@
import type { PageParam } from '@/api/index';
/**
* 文章分类表
*/
export interface CmsArticleCategory {
// 文章分类ID
categoryId?: number;
// 分类标识
categoryCode?: string;
// 分类名称
title?: string;
// 类型 0列表 1单页 2外链
type?: number;
// 分类图片
image?: string;
// 上级分类ID
parentId?: number;
// 路由/链接地址
path?: string;
// 组件路径
component?: string;
// 绑定的页面
pageId?: number;
// 用户ID
userId?: number;
// 文章数量
count?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
hide?: number;
// 是否推荐
recommend?: number;
// 是否显示在首页
showIndex?: number;
// 状态, 0正常, 1禁用
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
value?: number;
label?: string;
}
/**
* 文章分类表搜索条件
*/
export interface CmsArticleCategoryParam extends PageParam {
categoryId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleComment, CmsArticleCommentParam } from './model';
/**
* 分页查询文章评论表
*/
export async function pageCmsArticleComment(params: CmsArticleCommentParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleComment>>>(
'/cms/cms-article-comment/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询文章评论表列表
*/
export async function listCmsArticleComment(params?: CmsArticleCommentParam) {
const res = await request.get<ApiResult<CmsArticleComment[]>>(
'/cms/cms-article-comment',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加文章评论表
*/
export async function addCmsArticleComment(data: CmsArticleComment) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-article-comment',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改文章评论表
*/
export async function updateCmsArticleComment(data: CmsArticleComment) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-article-comment',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除文章评论表
*/
export async function removeCmsArticleComment(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-comment/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除文章评论表
*/
export async function removeBatchCmsArticleComment(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-comment/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询文章评论表
*/
export async function getCmsArticleComment(id: number) {
const res = await request.get<ApiResult<CmsArticleComment>>(
'/cms/cms-article-comment/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,47 @@
import type { PageParam } from '@/api';
/**
* 文章评论表
*/
export interface CmsArticleComment {
// 评价ID
commentId?: number;
// 文章ID
articleId?: number;
// 评分 (10好评 20中评 30差评)
score?: number;
// 评价内容
content?: string;
// 是否为图片评价
isPicture?: number;
// 评论者ID
userId?: number;
// 被评价者ID
toUserId?: number;
// 回复的评论ID
replyCommentId?: number;
// 回复者ID
replyUserId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0未读, 1已读
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 文章评论表搜索条件
*/
export interface CmsArticleCommentParam extends PageParam {
commentId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleContent, CmsArticleContentParam } from './model';
/**
* 分页查询文章记录表
*/
export async function pageCmsArticleContent(params: CmsArticleContentParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleContent>>>(
'/cms/cms-article-content/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询文章记录表列表
*/
export async function listCmsArticleContent(params?: CmsArticleContentParam) {
const res = await request.get<ApiResult<CmsArticleContent[]>>(
'/cms/cms-article-content',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加文章记录表
*/
export async function addCmsArticleContent(data: CmsArticleContent) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-article-content',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改文章记录表
*/
export async function updateCmsArticleContent(data: CmsArticleContent) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-article-content',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除文章记录表
*/
export async function removeCmsArticleContent(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-content/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除文章记录表
*/
export async function removeBatchCmsArticleContent(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-content/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询文章记录表
*/
export async function getCmsArticleContent(id: number) {
const res = await request.get<ApiResult<CmsArticleContent>>(
'/cms/cms-article-content/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,25 @@
import type { PageParam } from '@/api';
/**
* 文章记录表
*/
export interface CmsArticleContent {
//
id?: number;
// 文章ID
articleId?: number;
// 文章内容
content?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 文章记录表搜索条件
*/
export interface CmsArticleContentParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleCount, CmsArticleCountParam } from './model';
/**
* 分页查询点赞文章
*/
export async function pageCmsArticleCount(params: CmsArticleCountParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleCount>>>(
'/cms/cms-article-count/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询点赞文章列表
*/
export async function listCmsArticleCount(params?: CmsArticleCountParam) {
const res = await request.get<ApiResult<CmsArticleCount[]>>(
'/cms/cms-article-count',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加点赞文章
*/
export async function addCmsArticleCount(data: CmsArticleCount) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-article-count',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改点赞文章
*/
export async function updateCmsArticleCount(data: CmsArticleCount) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-article-count',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除点赞文章
*/
export async function removeCmsArticleCount(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-count/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除点赞文章
*/
export async function removeBatchCmsArticleCount(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-count/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询点赞文章
*/
export async function getCmsArticleCount(id: number) {
const res = await request.get<ApiResult<CmsArticleCount>>(
'/cms/cms-article-count/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,25 @@
import type { PageParam } from '@/api';
/**
* 点赞文章
*/
export interface CmsArticleCount {
// 主键ID
id?: number;
// 文章ID
articleId?: number;
// 用户ID
userId?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 点赞文章搜索条件
*/
export interface CmsArticleCountParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsArticleLike, CmsArticleLikeParam } from './model';
/**
* 分页查询点赞文章
*/
export async function pageCmsArticleLike(params: CmsArticleLikeParam) {
const res = await request.get<ApiResult<PageResult<CmsArticleLike>>>(
'/cms/cms-article-like/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询点赞文章列表
*/
export async function listCmsArticleLike(params?: CmsArticleLikeParam) {
const res = await request.get<ApiResult<CmsArticleLike[]>>(
'/cms/cms-article-like',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加点赞文章
*/
export async function addCmsArticleLike(data: CmsArticleLike) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-article-like',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改点赞文章
*/
export async function updateCmsArticleLike(data: CmsArticleLike) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-article-like',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除点赞文章
*/
export async function removeCmsArticleLike(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-like/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除点赞文章
*/
export async function removeBatchCmsArticleLike(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-article-like/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询点赞文章
*/
export async function getCmsArticleLike(id: number) {
const res = await request.get<ApiResult<CmsArticleLike>>(
'/cms/cms-article-like/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,25 @@
import type { PageParam } from '@/api';
/**
* 点赞文章
*/
export interface CmsArticleLike {
// 主键ID
id?: number;
// 文章ID
articleId?: number;
// 用户ID
userId?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 点赞文章搜索条件
*/
export interface CmsArticleLikeParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsComponents, CmsComponentsParam } from './model';
/**
* 分页查询组件
*/
export async function pageCmsComponents(params: CmsComponentsParam) {
const res = await request.get<ApiResult<PageResult<CmsComponents>>>(
'/cms/cms-components/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询组件列表
*/
export async function listCmsComponents(params?: CmsComponentsParam) {
const res = await request.get<ApiResult<CmsComponents[]>>(
'/cms/cms-components',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加组件
*/
export async function addCmsComponents(data: CmsComponents) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-components',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改组件
*/
export async function updateCmsComponents(data: CmsComponents) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-components',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除组件
*/
export async function removeCmsComponents(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-components/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除组件
*/
export async function removeBatchCmsComponents(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-components/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询组件
*/
export async function getCmsComponents(id: number) {
const res = await request.get<ApiResult<CmsComponents>>(
'/cms/cms-components/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,43 @@
import type { PageParam } from '@/api';
/**
* 组件
*/
export interface CmsComponents {
// ID
id?: number;
// 组件标题
title?: string;
// 关联导航ID
navigationId?: number;
// 组件类型
type?: string;
// 页面关键词
keywords?: string;
// 页面描述
description?: string;
// 组件路径
path?: string;
// 组件图标
icon?: string;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 组件搜索条件
*/
export interface CmsComponentsParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,102 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDesign, CmsDesignParam } from './model';
/**
* 分页查询页面管理记录表
*/
export async function pageCmsDesign(params: CmsDesignParam) {
const res = await request.get<ApiResult<PageResult<CmsDesign>>>(
'/cms/cms-design/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询页面管理记录表列表
*/
export async function listCmsDesign(params?: CmsDesignParam) {
const res = await request.get<ApiResult<CmsDesign[]>>(
'/cms/cms-design',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加页面管理记录表
*/
export async function addCmsDesign(data: CmsDesign) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-design',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改页面管理记录表
*/
export async function updateCmsDesign(data: CmsDesign) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-design',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除页面管理记录表
*/
export async function removeCmsDesign(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-design/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除页面管理记录表
*/
export async function removeBatchCmsDesign(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-design/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询页面管理记录表
*/
export async function getCmsDesign(id: number) {
const res = await request.get<ApiResult<CmsDesign>>(
'/cms/cms-design/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,60 @@
import type { PageParam } from '@/api/index';
/**
* 页面管理记录表
*/
export interface CmsDesign {
pageId?: number;
name?: string;
keywords?: string;
description?: string;
path?: string;
component?: string;
photo?: string;
content?: string;
// 类型
type?: string;
categoryId?: number;
// 宽
width?: string;
// 高
height?: string;
// 页面样式
style?: string;
// 附件
images?: string;
// 用户ID
userId?: number;
// 设为首页
home?: number;
// 排序
sortNumber?: number;
// 备注
comments?: string;
// 状态
status?: number;
// 创建时间
createTime?: string;
// 更新时间
updateTime?: string;
// 页面布局
layout?: string;
backgroundColor?: string;
// 关联网站导航ID
navigationId?: number;
showLayout?: boolean;
btn?: any[];
showBanner?: boolean;
buyUrl?: string;
demoUrl?: string;
account?: string;
docUrl?: string;
}
/**
* 页面管理记录表搜索条件
*/
export interface CmsDesignParam extends PageParam {
pageId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDesignRecord, CmsDesignRecordParam } from './model';
/**
* 分页查询页面组件表
*/
export async function pageCmsDesignRecord(params: CmsDesignRecordParam) {
const res = await request.get<ApiResult<PageResult<CmsDesignRecord>>>(
'/cms/cms-design-record/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询页面组件表列表
*/
export async function listCmsDesignRecord(params?: CmsDesignRecordParam) {
const res = await request.get<ApiResult<CmsDesignRecord[]>>(
'/cms/cms-design-record',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加页面组件表
*/
export async function addCmsDesignRecord(data: CmsDesignRecord) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-design-record',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改页面组件表
*/
export async function updateCmsDesignRecord(data: CmsDesignRecord) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-design-record',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除页面组件表
*/
export async function removeCmsDesignRecord(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-design-record/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除页面组件表
*/
export async function removeBatchCmsDesignRecord(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-design-record/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询页面组件表
*/
export async function getCmsDesignRecord(id: number) {
const res = await request.get<ApiResult<CmsDesignRecord>>(
'/cms/cms-design-record/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,51 @@
import type { PageParam } from '@/api';
/**
* 页面组件表
*/
export interface CmsDesignRecord {
// ID
id?: number;
// 关联导航ID
navigationId?: number;
parentId?: number;
pageId?: number;
// 组件
title?: string;
// 组件标识
dictCode?: string;
// 组件样式
styles?: string;
// 卡片阴影显示时机
shadow?: string;
// 页面关键词
keywords?: string;
// 页面描述
description?: string;
// 页面路由地址
path?: string;
// 缩列图
photo?: string;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 所属期次
periodId?: number;
}
/**
* 页面组件表搜索条件
*/
export interface CmsDesignRecordParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDocs, CmsDocsParam } from './model';
/**
* 分页查询文档管理记录表
*/
export async function pageCmsDocs(params: CmsDocsParam) {
const res = await request.get<ApiResult<PageResult<CmsDocs>>>(
'/cms/cms-docs/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询文档管理记录表列表
*/
export async function listCmsDocs(params?: CmsDocsParam) {
const res = await request.get<ApiResult<CmsDocs[]>>(
'/cms/cms-docs',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加文档管理记录表
*/
export async function addCmsDocs(data: CmsDocs) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-docs',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改文档管理记录表
*/
export async function updateCmsDocs(data: CmsDocs) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-docs',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除文档管理记录表
*/
export async function removeCmsDocs(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-docs/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除文档管理记录表
*/
export async function removeBatchCmsDocs(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-docs/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询文档管理记录表
*/
export async function getCmsDocs(id: number) {
const res = await request.get<ApiResult<CmsDocs>>(
'/cms/cms-docs/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,45 @@
import type { PageParam } from '@/api';
/**
* 文档管理记录表
*/
export interface CmsDocs {
// 文档ID
docsId?: number;
// 文档标题
title?: string;
// 上级目录
parentId?: number;
// 书籍ID
bookId?: number;
// 可见性(public,private,protected)
visibility?: string;
// 虚拟阅读量(仅用作展示)
virtualViews?: number;
// 实际阅读量
actualViews?: number;
// 用户ID
userId?: number;
// 备注
comments?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 文档管理记录表搜索条件
*/
export interface CmsDocsParam extends PageParam {
docsId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDocsBook, CmsDocsBookParam } from './model';
/**
* 分页查询书籍记录表
*/
export async function pageCmsDocsBook(params: CmsDocsBookParam) {
const res = await request.get<ApiResult<PageResult<CmsDocsBook>>>(
'/cms/cms-docs-book/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询书籍记录表列表
*/
export async function listCmsDocsBook(params?: CmsDocsBookParam) {
const res = await request.get<ApiResult<CmsDocsBook[]>>(
'/cms/cms-docs-book',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加书籍记录表
*/
export async function addCmsDocsBook(data: CmsDocsBook) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-docs-book',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改书籍记录表
*/
export async function updateCmsDocsBook(data: CmsDocsBook) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-docs-book',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除书籍记录表
*/
export async function removeCmsDocsBook(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-docs-book/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除书籍记录表
*/
export async function removeBatchCmsDocsBook(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-docs-book/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询书籍记录表
*/
export async function getCmsDocsBook(id: number) {
const res = await request.get<ApiResult<CmsDocsBook>>(
'/cms/cms-docs-book/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,37 @@
import type { PageParam } from '@/api';
/**
* 书籍记录表
*/
export interface CmsDocsBook {
// ID
bookId?: number;
// 书籍名称
name?: string;
// 书籍标识
code?: string;
// 封面图
photo?: string;
// 备注
comments?: string;
// 文档内容
content?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 书籍记录表搜索条件
*/
export interface CmsDocsBookParam extends PageParam {
bookId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDocsContent, CmsDocsContentParam } from './model';
/**
* 分页查询文档内容记录表
*/
export async function pageCmsDocsContent(params: CmsDocsContentParam) {
const res = await request.get<ApiResult<PageResult<CmsDocsContent>>>(
'/cms/cms-docs-content/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询文档内容记录表列表
*/
export async function listCmsDocsContent(params?: CmsDocsContentParam) {
const res = await request.get<ApiResult<CmsDocsContent[]>>(
'/cms/cms-docs-content',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加文档内容记录表
*/
export async function addCmsDocsContent(data: CmsDocsContent) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-docs-content',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改文档内容记录表
*/
export async function updateCmsDocsContent(data: CmsDocsContent) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-docs-content',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除文档内容记录表
*/
export async function removeCmsDocsContent(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-docs-content/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除文档内容记录表
*/
export async function removeBatchCmsDocsContent(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-docs-content/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询文档内容记录表
*/
export async function getCmsDocsContent(id: number) {
const res = await request.get<ApiResult<CmsDocsContent>>(
'/cms/cms-docs-content/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,25 @@
import type { PageParam } from '@/api';
/**
* 文档内容记录表
*/
export interface CmsDocsContent {
// ID
id?: number;
// 文档ID
docsId?: number;
// 文档内容
content?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 文档内容记录表搜索条件
*/
export interface CmsDocsContentParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,151 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsDomain, CmsDomainParam } from './model';
import {SERVER_API_URL} from "@/utils/server";
/**
* 分页查询网站域名记录表
*/
export async function pageCmsDomain(params: CmsDomainParam) {
const res = await request.get<ApiResult<PageResult<CmsDomain>>>(
SERVER_API_URL + '/cms/cms-domain/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询网站域名记录表列表
*/
export async function listCmsDomain(params?: CmsDomainParam) {
const res = await request.get<ApiResult<CmsDomain[]>>(
SERVER_API_URL + '/cms/cms-domain',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加网站域名记录表
*/
export async function addCmsDomain(data: CmsDomain) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改网站域名记录表
*/
export async function updateCmsDomain(data: CmsDomain) {
const res = await request.post<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain/domain',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除网站域名记录表
*/
export async function removeCmsDomain(id?: number) {
const res = await request.del<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除网站域名记录表
*/
export async function removeBatchCmsDomain(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
SERVER_API_URL + '/cms/cms-domain/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询网站域名记录表
*/
export async function getCmsDomain(id: number) {
const res = await request.get<ApiResult<CmsDomain>>(
SERVER_API_URL + '/cms/cms-domain/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 检查IP是否存在
*/
export async function checkExistence(
field: string,
value: string,
id?: number
) {
const res = await request.get<ApiResult<unknown>>(
SERVER_API_URL + '/cms/domain/existence',
{
params: { field, value, id }
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
export async function resolvable(id: number) {
const res = await request.get<ApiResult<CmsDomain>>(
SERVER_API_URL + '/cms/domain/resolvable/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
export async function getTenantIdByDomain(params: CmsDomainParam) {
const res = await request.get<ApiResult<PageResult<CmsDomain>>>(
SERVER_API_URL + '/cms/cms-domain/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,44 @@
import type { PageParam } from '@/api';
/**
* 网站域名记录表
*/
export interface CmsDomain {
// ID
id?: number;
// 类型 0赠送域名 1绑定域名
type?: number;
// 域名
domain?: string;
// 主机记录
hostName?: string;
// 记录值
hostValue?: string;
// 状态
status?: number;
// 排序号
sortNumber?: number;
// 网站ID
websiteId?: number;
// 租户ID
appId?: number;
// 用户ID
userId?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 网站域名记录表搜索条件
*/
export interface CmsDomainParam extends PageParam {
id?: number;
domain?: string;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsForm, CmsFormParam } from './model';
/**
* 分页查询表单设计表
*/
export async function pageCmsForm(params: CmsFormParam) {
const res = await request.get<ApiResult<PageResult<CmsForm>>>(
'/cms/cms-form/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询表单设计表列表
*/
export async function listCmsForm(params?: CmsFormParam) {
const res = await request.get<ApiResult<CmsForm[]>>(
'/cms/cms-form',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加表单设计表
*/
export async function addCmsForm(data: CmsForm) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-form',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改表单设计表
*/
export async function updateCmsForm(data: CmsForm) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-form',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除表单设计表
*/
export async function removeCmsForm(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-form/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除表单设计表
*/
export async function removeBatchCmsForm(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-form/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询表单设计表
*/
export async function getCmsForm(id: number) {
const res = await request.get<ApiResult<CmsForm>>(
'/cms/cms-form/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,53 @@
import type { PageParam } from '@/api';
/**
* 表单设计表
*/
export interface CmsForm {
// ID
formId?: number;
// 表单标题
name?: string;
// 顶部图片
photo?: string;
// 背景图片
background?: string;
// 视频文件
video?: string;
// 提交次数
submitNumber?: number;
// 页面布局
layout?: string;
// 是否隐藏顶部图片
hidePhoto?: number;
// 是否隐藏背景图片
hideBackground?: number;
// 是否隐藏视频
hideVideo?: number;
// 背景图片透明度
opacity?: string;
// 用户ID
userId?: number;
// 商户ID
merchantId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 表单设计表搜索条件
*/
export interface CmsFormParam extends PageParam {
formId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsFormRecord, CmsFormRecordParam } from './model';
/**
* 分页查询表单数据记录表
*/
export async function pageCmsFormRecord(params: CmsFormRecordParam) {
const res = await request.get<ApiResult<PageResult<CmsFormRecord>>>(
'/cms/cms-form-record/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询表单数据记录表列表
*/
export async function listCmsFormRecord(params?: CmsFormRecordParam) {
const res = await request.get<ApiResult<CmsFormRecord[]>>(
'/cms/cms-form-record',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加表单数据记录表
*/
export async function addCmsFormRecord(data: CmsFormRecord) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-form-record',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改表单数据记录表
*/
export async function updateCmsFormRecord(data: CmsFormRecord) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-form-record',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除表单数据记录表
*/
export async function removeCmsFormRecord(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-form-record/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除表单数据记录表
*/
export async function removeBatchCmsFormRecord(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-form-record/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询表单数据记录表
*/
export async function getCmsFormRecord(id: number) {
const res = await request.get<ApiResult<CmsFormRecord>>(
'/cms/cms-form-record/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,41 @@
import type { PageParam } from '@/api/index';
/**
* 表单数据记录表
*/
export interface CmsFormRecord {
// ID
formRecordId?: number;
// 手机号
phone?: string;
// 表单数据
formData?: string;
// 表单ID
formId?: number;
// 用户ID
userId?: number;
// 商户ID
merchantId?: number;
// 姓名
name?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 表单数据记录表搜索条件
*/
export interface CmsFormRecordParam extends PageParam {
formRecordId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,105 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsLang, CmsLangParam } from './model';
/**
* 分页查询国际化
*/
export async function pageCmsLang(params: CmsLangParam) {
const res = await request.get<ApiResult<PageResult<CmsLang>>>(
'/cms/cms-lang/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询国际化列表
*/
export async function listCmsLang(params?: CmsLangParam) {
const res = await request.get<ApiResult<CmsLang[]>>(
'/cms/cms-lang',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加国际化
*/
export async function addCmsLang(data: CmsLang) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-lang',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改国际化
*/
export async function updateCmsLang(data: CmsLang) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-lang',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除国际化
*/
export async function removeCmsLang(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-lang/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除国际化
*/
export async function removeBatchCmsLang(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-lang/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询国际化
*/
export async function getCmsLang(id: number) {
const res = await request.get<ApiResult<CmsLang>>(
'/cms/cms-lang/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,39 @@
import type { PageParam } from '@/api';
/**
* 国际化
*/
export interface CmsLang {
// ID
id?: number;
// 名称
name?: string;
// 菜单组件地址, 目录可为空
code?: string;
// 启用语言
lang?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 0禁用 1启用
enable?: boolean;
// 状态, 0禁用 1启用
status?: boolean;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 国际化搜索条件
*/
export interface CmsLangParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,105 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsLangLog, CmsLangLogParam } from './model';
/**
* 分页查询国际化记录启用
*/
export async function pageCmsLangLog(params: CmsLangLogParam) {
const res = await request.get<ApiResult<PageResult<CmsLangLog>>>(
'/cms/cms-lang-log/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询国际化记录启用列表
*/
export async function listCmsLangLog(params?: CmsLangLogParam) {
const res = await request.get<ApiResult<CmsLangLog[]>>(
'/cms/cms-lang-log',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加国际化记录启用
*/
export async function addCmsLangLog(data: CmsLangLog) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-lang-log',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改国际化记录启用
*/
export async function updateCmsLangLog(data: CmsLangLog) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-lang-log',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除国际化记录启用
*/
export async function removeCmsLangLog(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-lang-log/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除国际化记录启用
*/
export async function removeBatchCmsLangLog(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-lang-log/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询国际化记录启用
*/
export async function getCmsLangLog(id: number) {
const res = await request.get<ApiResult<CmsLangLog>>(
'/cms/cms-lang-log/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,27 @@
import type { PageParam } from '@/api';
/**
* 国际化记录启用
*/
export interface CmsLangLog {
// ID
id?: number;
// 关联ID
langId?: number;
// 编码
code?: string;
// 名称
lang?: string;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 国际化记录启用搜索条件
*/
export interface CmsLangLogParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsLink, CmsLinkParam } from './model';
/**
* 分页查询常用链接
*/
export async function pageCmsLink(params: CmsLinkParam) {
const res = await request.get<ApiResult<PageResult<CmsLink>>>(
'/cms/cms-link/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询常用链接列表
*/
export async function listCmsLink(params?: CmsLinkParam) {
const res = await request.get<ApiResult<CmsLink[]>>(
'/cms/cms-link',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加常用链接
*/
export async function addCmsLink(data: CmsLink) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-link',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改常用链接
*/
export async function updateCmsLink(data: CmsLink) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-link',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除常用链接
*/
export async function removeCmsLink(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-link/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除常用链接
*/
export async function removeBatchCmsLink(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-link/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询常用链接
*/
export async function getCmsLink(id: number) {
const res = await request.get<ApiResult<CmsLink>>(
'/cms/cms-link/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,43 @@
import type { PageParam } from '@/api';
/**
* 常用链接
*/
export interface CmsLink {
// 自增ID
id?: number;
// 链接名称
name?: string;
// 图标
icon?: string;
// 链接地址
url?: string;
// 链接分类
linkType?: string;
// 应用ID
appId?: number;
// 用户ID
userId?: number;
// 是否推荐
recommend?: number;
// 备注
comments?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 状态, 0正常, 1待确认
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 常用链接搜索条件
*/
export interface CmsLinkParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsModel, CmsModelParam } from './model';
/**
* 分页查询模型
*/
export async function pageCmsModel(params: CmsModelParam) {
const res = await request.get<ApiResult<PageResult<CmsModel>>>(
'/cms/cms-model/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询模型列表
*/
export async function listCmsModel(params?: CmsModelParam) {
const res = await request.get<ApiResult<CmsModel[]>>(
'/cms/cms-model',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加模型
*/
export async function addCmsModel(data: CmsModel) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-model',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改模型
*/
export async function updateCmsModel(data: CmsModel) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-model',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除模型
*/
export async function removeCmsModel(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-model/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除模型
*/
export async function removeBatchCmsModel(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-model/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询模型
*/
export async function getCmsModel(id: number) {
const res = await request.get<ApiResult<CmsModel>>(
'/cms/cms-model/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,57 @@
import type { PageParam } from '@/api/index';
/**
* 模型
*/
export interface CmsModel {
// ID
modelId?: number;
// 模型名称
name?: string;
// 唯一标识
model?: string;
// 菜单路由地址
path?: string;
// 菜单组件地址, 目录可为空
component?: string;
// 模型banner图片
banner?: string;
// 缩列图
thumb?: string;
// 封面图宽
imageWidth?: string;
// 封面图高
imageHeight?: string;
// 样式
style?: string;
// Banner上的标题
title?: string;
// Banner上的描述
desc?: string;
// 列表显示方式(10小图展示 20大图展示)
showType?: number;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0已发布, 1待审核 2已驳回 3违规内容
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
}
/**
* 模型搜索条件
*/
export interface CmsModelParam extends PageParam {
modelId?: number;
keywords?: string;
}

106
src/api/cms/cmsMp/index.ts Normal file
View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMp, CmsMpParam } from './model';
/**
* 分页查询小程序信息
*/
export async function pageCmsMp(params: CmsMpParam) {
const res = await request.get<ApiResult<PageResult<CmsMp>>>(
'/cms/cms-mp/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询小程序信息列表
*/
export async function listCmsMp(params?: CmsMpParam) {
const res = await request.get<ApiResult<CmsMp[]>>(
'/cms/cms-mp',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加小程序信息
*/
export async function addCmsMp(data: CmsMp) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-mp',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改小程序信息
*/
export async function updateCmsMp(data: CmsMp) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-mp',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除小程序信息
*/
export async function removeCmsMp(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除小程序信息
*/
export async function removeBatchCmsMp(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询小程序信息
*/
export async function getCmsMp(id: number) {
const res = await request.get<ApiResult<CmsMp>>(
'/cms/cms-mp/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,61 @@
import type { PageParam } from '@/api';
/**
* 小程序信息
*/
export interface CmsMp {
// ID
mpId?: number;
// 是否主账号
type?: number;
// 小程序ID
appId?: string;
// 小程序密钥
appSecret?: string;
// 小程序名称
mpName?: string;
// 小程序简称
shortName?: string;
// 头像
avatar?: string;
// 小程序码
mpQrcode?: string;
// 微信认证
authentication?: number;
// 主体信息
companyName?: string;
// 小程序备案
icpNo?: string;
// 登录邮箱
email?: string;
// 登录密码
password?: string;
// 原始ID
ghId?: string;
// 入口页面
mainPath?: string;
// 过期时间
expirationTime?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 介绍
comments?: string;
// 用户ID
userId?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序信息搜索条件
*/
export interface CmsMpParam extends PageParam {
mpId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpAd, CmsMpAdParam } from './model';
/**
* 分页查询小程序广告位
*/
export async function pageCmsMpAd(params: CmsMpAdParam) {
const res = await request.get<ApiResult<PageResult<CmsMpAd>>>(
'/cms/cms-mp-ad/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询小程序广告位列表
*/
export async function listCmsMpAd(params?: CmsMpAdParam) {
const res = await request.get<ApiResult<CmsMpAd[]>>(
'/cms/cms-mp-ad',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加小程序广告位
*/
export async function addCmsMpAd(data: CmsMpAd) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-mp-ad',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改小程序广告位
*/
export async function updateCmsMpAd(data: CmsMpAd) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-mp-ad',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除小程序广告位
*/
export async function removeCmsMpAd(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-ad/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除小程序广告位
*/
export async function removeBatchCmsMpAd(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-ad/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询小程序广告位
*/
export async function getCmsMpAd(id: number) {
const res = await request.get<ApiResult<CmsMpAd>>(
'/cms/cms-mp-ad/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,47 @@
import type { PageParam } from '@/api';
/**
* 小程序广告位
*/
export interface CmsMpAd {
// ID
adId?: number;
// 页面ID
pageId?: number;
// 广告类型
adType?: string;
// 广告位名称
name?: string;
// 宽
width?: string;
// 高
height?: string;
// 广告图片
images?: string;
// 路由/链接地址
path?: string;
// 页面名称
pageName?: string;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序广告位搜索条件
*/
export interface CmsMpAdParam extends PageParam {
adId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpField, CmsMpFieldParam } from './model';
/**
* 分页查询小程序配置
*/
export async function pageCmsMpField(params: CmsMpFieldParam) {
const res = await request.get<ApiResult<PageResult<CmsMpField>>>(
'/cms/cms-mp-field/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询小程序配置列表
*/
export async function listCmsMpField(params?: CmsMpFieldParam) {
const res = await request.get<ApiResult<CmsMpField[]>>(
'/cms/cms-mp-field',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加小程序配置
*/
export async function addCmsMpField(data: CmsMpField) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-mp-field',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改小程序配置
*/
export async function updateCmsMpField(data: CmsMpField) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-mp-field',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除小程序配置
*/
export async function removeCmsMpField(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-field/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除小程序配置
*/
export async function removeBatchCmsMpField(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-field/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询小程序配置
*/
export async function getCmsMpField(id: number) {
const res = await request.get<ApiResult<CmsMpField>>(
'/cms/cms-mp-field/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,35 @@
import type { PageParam } from '@/api';
/**
* 小程序配置
*/
export interface CmsMpField {
// 自增ID
id?: number;
// 类型0文本 1图片 2其他
type?: number;
// 名称
name?: string;
// 备注
comments?: string;
// 名称
value?: string;
// 页面ID
pageId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序配置搜索条件
*/
export interface CmsMpFieldParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpMenu, CmsMpMenuParam } from './model';
/**
* 分页查询小程序端菜单
*/
export async function pageCmsMpMenu(params: CmsMpMenuParam) {
const res = await request.get<ApiResult<PageResult<CmsMpMenu>>>(
'/cms/cms-mp-menu/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询小程序端菜单列表
*/
export async function listCmsMpMenu(params?: CmsMpMenuParam) {
const res = await request.get<ApiResult<CmsMpMenu[]>>(
'/cms/cms-mp-menu',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加小程序端菜单
*/
export async function addCmsMpMenu(data: CmsMpMenu) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-mp-menu',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改小程序端菜单
*/
export async function updateCmsMpMenu(data: CmsMpMenu) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-mp-menu',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除小程序端菜单
*/
export async function removeCmsMpMenu(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-menu/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除小程序端菜单
*/
export async function removeBatchCmsMpMenu(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-menu/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询小程序端菜单
*/
export async function getCmsMpMenu(id: number) {
const res = await request.get<ApiResult<CmsMpMenu>>(
'/cms/cms-mp-menu/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,79 @@
import type { PageParam } from '@/api';
/**
* 小程序端菜单
*/
export interface CmsMpMenu {
// ID
menuId?: number;
// 上级id, 0是顶级
parentId?: number;
// 菜单名称
title?: string;
// 类型 0功能图标 1订单状态图标 2首页导航图标 3 商城导航图标 4管理人员功能图标
type?: number;
// 是否微信小程序菜单
isMpWeixin?: string;
// 菜单路由地址
path?: string;
// 菜单组件地址, 目录可为空
component?: string;
// 打开位置
target?: string;
// 菜单图标
avatar?: string;
// 图标颜色
color?: string;
// 上传图标
icon?: string;
// 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
hide?: number;
// 位置 0不限 1顶部 2底部
position?: number;
// 0 第一行 1第二行
rows?: number;
// 菜单侧栏选中的path
active?: string;
// 其它路由元信息
meta?: string;
// 绑定的页面
pageId?: number;
// 绑定的文章分类ID
articleCategoryId?: number;
// 绑定的文章ID
articleId?: number;
// 绑定的表单ID
formId?: number;
// 绑定的书籍标识
bookCode?: string;
// 绑定的商品分类ID
goodsCategoryId?: number;
// 绑定的商品ID
goodsId?: number;
// 用户ID
userId?: number;
// 是否管理人员可见
adminShow?: number;
// 设为首页
home?: number;
// 分组名称
groupName?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序端菜单搜索条件
*/
export interface CmsMpMenuParam extends PageParam {
menuId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsMpPages, CmsMpPagesParam } from './model';
/**
* 分页查询小程序页面
*/
export async function pageCmsMpPages(params: CmsMpPagesParam) {
const res = await request.get<ApiResult<PageResult<CmsMpPages>>>(
'/cms/cms-mp-pages/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询小程序页面列表
*/
export async function listCmsMpPages(params?: CmsMpPagesParam) {
const res = await request.get<ApiResult<CmsMpPages[]>>(
'/cms/cms-mp-pages',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加小程序页面
*/
export async function addCmsMpPages(data: CmsMpPages) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-mp-pages',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改小程序页面
*/
export async function updateCmsMpPages(data: CmsMpPages) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-mp-pages',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除小程序页面
*/
export async function removeCmsMpPages(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-pages/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除小程序页面
*/
export async function removeBatchCmsMpPages(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-mp-pages/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询小程序页面
*/
export async function getCmsMpPages(id: number) {
const res = await request.get<ApiResult<CmsMpPages>>(
'/cms/cms-mp-pages/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,47 @@
import type { PageParam } from '@/api';
/**
* 小程序页面
*/
export interface CmsMpPages {
// ID
id?: number;
// 上级id, 0是顶级
parentId?: number;
// 页面名称
title?: string;
// 页面路径
path?: string;
// 设为首页
home?: number;
// 分包
subpackage?: string;
// 图标
icon?: string;
// 未选中图标
iconPath?: string;
// 选中的图标
selectedIconPath?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 用户ID
userId?: number;
// 状态, 0正常, 1冻结
status?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序页面搜索条件
*/
export interface CmsMpPagesParam extends PageParam {
id?: number;
keywords?: string;
}

View File

@@ -0,0 +1,138 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsNavigation, CmsNavigationParam } from './model';
/**
* 分页查询网站导航记录表
*/
export async function pageCmsNavigation(params: CmsNavigationParam) {
const res = await request.get<ApiResult<PageResult<CmsNavigation>>>(
'/cms/cms-navigation/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询网站导航记录表列表
*/
export async function listCmsNavigation(params?: CmsNavigationParam) {
const res = await request.get<ApiResult<CmsNavigation[]>>(
'/cms/cms-navigation',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询导航列表(树形结构)
*/
export async function treeNavigation(params?: CmsNavigationParam) {
const res = await request.get<ApiResult<CmsNavigation[]>>(
'/cms/cms-navigation/tree',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加网站导航记录表
*/
export async function addCmsNavigation(data: CmsNavigation) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-navigation',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改网站导航记录表
*/
export async function updateCmsNavigation(data: CmsNavigation) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-navigation',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除网站导航记录表
*/
export async function removeCmsNavigation(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-navigation/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除网站导航记录表
*/
export async function removeBatchCmsNavigation(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-navigation/batch',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询网站导航记录表
*/
export async function getCmsNavigation(id: number) {
const res = await request.get<ApiResult<CmsNavigation>>(
'/cms/cms-navigation/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
export async function getNavigationByPath(params: CmsNavigationParam) {
const res = await request.get<ApiResult<CmsNavigation>>(
'/cms/cms-navigation/getNavigationByPath',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据code查询导航
*/
export async function getByCode(code: string) {
const res = await request.get<ApiResult<CmsNavigation>>(
'/cms/cms-navigation/getByCode/' + code
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,117 @@
import type {PageParam} from '@/api/index';
import type {CmsDesign} from "@/api/cms/cmsDesign/model";
import type {CmsModel} from "@/api/cms/cmsModel/model";
import {CmsArticle} from "@/api/cms/cmsArticle/model";
/**
* 网站导航记录表
*/
export interface CmsNavigation {
// ID
navigationId?: number;
// 上级id, 0是顶级
parentId?: number;
// 菜单名称
title?: string;
// 模型
model?: string;
// 标识
code?: string;
// 菜单路由地址
path?: string;
// 菜单组件地址, 目录可为空
component?: string;
// 组件路径
componentPath?: string;
// 打开位置
target?: string;
// 菜单图标
icon?: string;
// banner图片
banner?: string;
// 图标颜色
color?: string;
// 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
hide?: number;
// 可见类型 0所有人 1登录可见 2密码可见
permission?: number;
// 访问密码
password?: string;
// 位置 0不限 1顶部 2底部
position?: number;
// 仅在顶部显示
top?: number;
// 仅在底部显示
bottom?: number;
// 菜单侧栏选中的path
active?: string;
// 其它路由元信息
meta?: string;
// css样式
style?: string;
// 父级栏目路由
parentPath?: string;
// 父级栏目名称
parentName?: string;
// 模型名称
modelName?: string;
// 类型(模型)
type?: string;
// 绑定的页面(已废弃)
pageId?: number;
// 项目ID
itemId?: number;
// 是否微信小程序菜单
isMpWeixin?: string;
// 用户ID
userId?: number;
// 设为首页
home?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 是否删除, 0否, 1是
deleted?: number;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 父级栏目
parent?: CmsNavigation;
// 子级栏目
children?: CmsNavigation[];
// 模型信息
modelInfo?: CmsModel;
// 栏目名称
categoryName?: string;
// 是否禁用
disabled?: boolean;
// 链接地址
design?: CmsDesign;
// 子级数量
childHeight?: number,
// 是否展开
showChild?: boolean
// 布局
layout?: any;
// 标题
label?: string;
// 值
value?: number;
// 文章列表
articles?: CmsArticle[];
}
/**
* 网站导航记录表搜索条件
*/
export interface CmsNavigationParam extends PageParam {
navigationId?: number;
parentId?: number;
hide?: number;
model?: string;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsOrder, CmsOrderParam } from './model';
/**
* 分页查询订单
*/
export async function pageCmsOrder(params: CmsOrderParam) {
const res = await request.get<ApiResult<PageResult<CmsOrder>>>(
'/cms/cms-order/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询订单列表
*/
export async function listCmsOrder(params?: CmsOrderParam) {
const res = await request.get<ApiResult<CmsOrder[]>>(
'/cms/cms-order',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加订单
*/
export async function addCmsOrder(data: CmsOrder) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-order',
data
);
if (res.code === 0) {
return res;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改订单
*/
export async function updateCmsOrder(data: CmsOrder) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-order',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除订单
*/
export async function removeCmsOrder(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-order/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除订单
*/
export async function removeBatchCmsOrder(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-order/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询订单
*/
export async function getCmsOrder(id: number) {
const res = await request.get<ApiResult<CmsOrder>>(
'/cms/cms-order/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,69 @@
import type { PageParam } from '@/api/index';
/**
* 订单
*/
export interface CmsOrder {
// 订单号
orderId?: number;
// 关联模型
model?: string;
// 订单标题
title?: string;
// 订单编号
orderNo?: string;
// 订单类型0商城 1询价 2留言
type?: number;
// 关联文章ID
articleId?: number;
// 真实姓名
realName?: string;
// 手机号码
phone?: string;
// 电子邮箱
email?: string;
// 收货地址
address?: string;
// 订单内容
content?: string;
// 订单总额
totalPrice?: string;
// 实际付款
payPrice?: string;
// 报价询价
price?: string;
// 购买数量
totalNum?: number;
// 二维码地址,保存订单号,支付成功后才生成
qrcode?: string;
// 下单渠道0网站 1小程序 2其他
channel?: number;
// 过期时间
expirationTime?: string;
// 订单是否已结算(0未结算 1已结算)
isSettled?: number;
// 用户id
userId?: number;
// 备注
comments?: string;
// 排序号
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 图像验证码
code?: string;
// 图像验证码内容
text?: string;
}
/**
* 订单搜索条件
*/
export interface CmsOrderParam extends PageParam {
orderId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsSpec, CmsSpecParam } from './model';
/**
* 分页查询规格
*/
export async function pageCmsSpec(params: CmsSpecParam) {
const res = await request.get<ApiResult<PageResult<CmsSpec>>>(
'/cms/cms-spec/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询规格列表
*/
export async function listCmsSpec(params?: CmsSpecParam) {
const res = await request.get<ApiResult<CmsSpec[]>>(
'/cms/cms-spec',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加规格
*/
export async function addCmsSpec(data: CmsSpec) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-spec',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改规格
*/
export async function updateCmsSpec(data: CmsSpec) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-spec',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除规格
*/
export async function removeCmsSpec(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-spec/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除规格
*/
export async function removeBatchCmsSpec(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-spec/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询规格
*/
export async function getCmsSpec(id: number) {
const res = await request.get<ApiResult<CmsSpec>>(
'/cms/cms-spec/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,35 @@
import type { PageParam } from '@/api';
/**
* 规格
*/
export interface CmsSpec {
// 规格ID
specId?: number;
// 规格名称
specName?: string;
// 规格值
specValue?: string;
// 创建用户
userId?: number;
// 更新者
updater?: number;
// 备注
comments?: string;
// 状态, 0正常, 1待修,2异常已修3异常未修
status?: number;
// 排序号
sortNumber?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 规格搜索条件
*/
export interface CmsSpecParam extends PageParam {
specId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsSpecValue, CmsSpecValueParam } from './model';
/**
* 分页查询规格值
*/
export async function pageCmsSpecValue(params: CmsSpecValueParam) {
const res = await request.get<ApiResult<PageResult<CmsSpecValue>>>(
'/cms/cms-spec-value/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询规格值列表
*/
export async function listCmsSpecValue(params?: CmsSpecValueParam) {
const res = await request.get<ApiResult<CmsSpecValue[]>>(
'/cms/cms-spec-value',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加规格值
*/
export async function addCmsSpecValue(data: CmsSpecValue) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-spec-value',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改规格值
*/
export async function updateCmsSpecValue(data: CmsSpecValue) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-spec-value',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除规格值
*/
export async function removeCmsSpecValue(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-spec-value/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除规格值
*/
export async function removeBatchCmsSpecValue(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-spec-value/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询规格值
*/
export async function getCmsSpecValue(id: number) {
const res = await request.get<ApiResult<CmsSpecValue>>(
'/cms/cms-spec-value/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,29 @@
import type { PageParam } from '@/api';
/**
* 规格值
*/
export interface CmsSpecValue {
// 规格值ID
specValueId?: number;
// 规格组ID
specId?: number;
// 规格值
specValue?: string;
// 备注
comments?: string;
// 排序号
sortNumber?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 规格值搜索条件
*/
export interface CmsSpecValueParam extends PageParam {
specValueId?: number;
keywords?: string;
}

View File

@@ -0,0 +1,147 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { CmsWebsite, CmsWebsiteParam } from './model';
/**
* 分页查询网站信息记录表
*/
export async function pageCmsWebsite(params: CmsWebsiteParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsite>>>(
'/cms/cms-website/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询网站
*/
export async function getCmsWebsiteAll(id: number) {
const res = await request.get<ApiResult<CmsWebsite>>(
'/cms/cms-website/getAll/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询网站信息记录表列表
*/
export async function listCmsWebsite(params?: CmsWebsiteParam) {
const res = await request.get<ApiResult<CmsWebsite[]>>(
'/cms/cms-website',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加网站信息记录表
*/
export async function addCmsWebsite(data: CmsWebsite) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-website',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改网站信息记录表
*/
export async function updateCmsWebsite(data: CmsWebsite) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-website',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除网站信息记录表
*/
export async function removeCmsWebsite(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-website/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除网站信息记录表
*/
export async function removeBatchCmsWebsite(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-website/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询网站信息记录表
*/
export async function getCmsWebsite(id: number) {
const res = await request.get<ApiResult<CmsWebsite>>(
'/cms/cms-website/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 清除缓存
*/
export async function removeSiteInfoCache(key?: string) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-website/clearSiteInfo/' + key
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 分页查询网站信息记录表
* @param params
*/
export async function pageCmsWebsiteAll(params: CmsWebsiteParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsite>>>(
'/cms/cms-website/pageAll',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,138 @@
import type { PageParam } from '@/api/index';
import type {CmsNavigation} from "@/api/cms/cmsNavigation/model";
/**
* 网站信息记录表
*/
export interface CmsWebsite {
// 站点ID
websiteId?: number;
// 网站名称
websiteName?: string;
// 网站标识
websiteCode?: string;
// 网站LOGO
websiteIcon?: string;
// 网站LOGO
websiteLogo?: string;
// 网站LOGO(深色模式)
websiteDarkLogo?: string;
// 网站类型
websiteType?: string;
// 网站关键词
keywords?: string;
// 域名前缀
prefix?: string;
// 绑定域名
domain?: string;
// 全局样式
style?: string;
// 后台管理地址
adminUrl?: string;
// 应用版本 10免费版 20专业版 30永久授权
version?: number;
// 服务到期时间
expirationTime?: string;
// 模版ID
templateId?: number;
// 行业类型(父级)
industryParent?: string;
// 行业类型(子级)
industryChild?: string;
// 企业ID
companyId?: number;
// 所在国家
country?: string;
// 所在省份
province?: string;
// 所在城市
city?: string;
// 所在辖区
region?: string;
// 经度
longitude?: string;
// 纬度
latitude?: string;
// 街道地址
address?: string;
// 联系电话
phone?: string;
// 电子邮箱
email?: string;
// ICP备案号
icpNo?: string;
// 公安备案
policeNo?: string;
// 备注
comments?: string;
// 是否推荐
recommend?: number;
// 运行状态
running?: number;
// 状态 0未开通 1运行中 2维护中 3已关闭 4已欠费停机 5违规关停
status?: number;
// 维护说明
statusText?: string;
// 关闭说明
statusClose?: string;
// 状态图标
statusIcon?: string;
// 全局样式
styles?: string;
// 排序号
sortNumber?: number;
// 用户ID
userId?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
// 修改时间
updateTime?: string;
// 网站配置
config?: any;
topNavs?: CmsNavigation[];
bottomNavs?: CmsNavigation[];
loginUser?: any;
search?: boolean;
}
export interface AppInfo {
appId?: number;
appName?: string;
description?: string;
keywords?: string;
appCode?: string;
mpQrCode?: string;
title?: string;
logo?: string;
icon?: string;
domain?: string;
running?: number;
version?: number;
expirationTime?: string;
expired?: boolean;
expiredDays?: number;
soon?: number;
statusIcon?: string;
statusText?: string;
config?: Object;
serverTime?: Object;
topNavs?: CmsNavigation[];
bottomNavs?: CmsNavigation[];
setting?: Object;
createTime?: string;
}
/**
* 网站信息记录表搜索条件
*/
export interface CmsWebsiteParam extends PageParam {
websiteId?: number;
status?: number;
phone?: string;
keywords?: string;
}

View File

@@ -0,0 +1,129 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type {CmsWebsiteField, CmsWebsiteFieldParam, Config} from './model';
/**
* 分页查询应用参数
*/
export async function pageCmsWebsiteField(params: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<PageResult<CmsWebsiteField>>>(
'/cms/cms-website-field/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询应用参数列表
*/
export async function listCmsWebsiteField(params?: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<CmsWebsiteField[]>>(
'/cms/cms-website-field',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加应用参数
*/
export async function addCmsWebsiteField(data: CmsWebsiteField) {
const res = await request.post<ApiResult<unknown>>(
'/cms/cms-website-field',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改应用参数
*/
export async function updateCmsWebsiteField(data: CmsWebsiteField) {
const res = await request.put<ApiResult<unknown>>(
'/cms/cms-website-field',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除应用参数
*/
export async function removeCmsWebsiteField(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-website-field/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除应用参数
*/
export async function removeBatchCmsWebsiteField(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/cms-website-field/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询应用参数
*/
export async function getCmsWebsiteField(id: number) {
const res = await request.get<ApiResult<CmsWebsiteField>>(
'/cms/cms-website-field/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 恢复项目参数
*/
export async function undeleteWebsiteField(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/website-field/undelete/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询项目参数列表
*/
export async function configWebsiteField(params?: CmsWebsiteFieldParam) {
const res = await request.get<ApiResult<Config>>(
'/cms/cms-website-field/config',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,63 @@
import type { PageParam } from '@/api/index';
/**
* 应用参数
*/
export interface CmsWebsiteField {
// 自增ID
id?: number;
// 类型0文本 1图片 2其他
type?: number;
// 名称
name?: string;
// 默认值
defaultValue?: string;
// 可修改的值 [on|off]
modifyRange?: string;
// 备注
comments?: string;
// css样式
style?: string;
// 名称
value?: string;
// 排序(数字越小越靠前)
sortNumber?: number;
// 是否删除, 0否, 1是
deleted?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 应用参数搜索条件
*/
export interface CmsWebsiteFieldParam extends PageParam {
id?: number;
name?: string;
keywords?: string;
}
export interface Config {
siteName?: string;
siteLogo?: string;
domain?: string;
icpNo?: string;
copyright?: string;
loginBgImg?: string;
address?: string;
tel?: string;
theme?: string;
workDay?: string;
kefu2?: string;
kefu1?: string;
email?: string;
loginTitle?: string;
sysLogo?: string;
vipText?: string;
vipComments?: string;
deliveryText?: string;
guaranteeText?: string;
openComments?: string;
}

113
src/api/cms/link/index.ts Normal file
View File

@@ -0,0 +1,113 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { Link, LinkParam } from './model';
/**
* 分页查询链接
*/
export async function pageLink(params: LinkParam) {
const res = await request.get<ApiResult<PageResult<Link>>>(
'/oa/link/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询链接列表
*/
export async function listLink(params?: LinkParam) {
const res = await request.get<ApiResult<Link[]>>(
'/oa/link',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加链接
*/
export async function addLink(data: Link) {
const res = await request.post<ApiResult<unknown>>(
'/oa/link',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改链接
*/
export async function updateLink(data: Link) {
const res = await request.put<ApiResult<unknown>>(
'/oa/link',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除链接
*/
export async function removeLink(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/oa/link/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除链接
*/
export async function removeBatchLink(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/oa/link/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 检查IP是否存在
*/
export async function checkExistence(
field: string,
value: string,
id?: number
) {
const res = await request.get<ApiResult<unknown>>(
'/oa/link/existence',
{
params: { field, value, id }
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,31 @@
import type { PageParam } from '@/api/index';
/**
* 链接
*/
export interface Link {
id?: number;
name?: string;
icon?: string;
url?: string;
linkType?: string;
appId?: number;
categoryId?: number;
userId?: number;
comments?: string;
recommend?: number;
sortNumber?: number;
deleted?: number;
status?: number;
createTime?: number;
}
/**
* 链接搜索条件
*/
export interface LinkParam extends PageParam {
id?: number;
linkType?: string;
categoryId?: number;
name?: string;
}

View File

@@ -0,0 +1,106 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { MpOfficialMenu, MpOfficialMenuParam } from './model';
/**
* 分页查询小程序端菜单
*/
export async function pageMpOfficialMenu(params: MpOfficialMenuParam) {
const res = await request.get<ApiResult<PageResult<MpOfficialMenu>>>(
'/cms/mp-official-menu/page',
{
params
}
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询小程序端菜单列表
*/
export async function listMpOfficialMenu(params?: MpOfficialMenuParam) {
const res = await request.get<ApiResult<MpOfficialMenu[]>>(
'/cms/mp-official-menu',
{
params
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加小程序端菜单
*/
export async function addMpOfficialMenu(data: MpOfficialMenu) {
const res = await request.post<ApiResult<unknown>>(
'/cms/mp-official-menu',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改小程序端菜单
*/
export async function updateMpOfficialMenu(data: MpOfficialMenu) {
const res = await request.put<ApiResult<unknown>>(
'/cms/mp-official-menu',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除小程序端菜单
*/
export async function removeMpOfficialMenu(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/cms/mp-official-menu/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除小程序端菜单
*/
export async function removeBatchMpOfficialMenu(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/cms/mp-official-menu/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询小程序端菜单
*/
export async function getMpOfficialMenu(id: number) {
const res = await request.get<ApiResult<MpOfficialMenu>>(
'/cms/mp-official-menu/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,37 @@
import type { PageParam } from '@/api';
/**
* 小程序端菜单
*/
export interface MpOfficialMenu {
// ID
id?: number;
// 上级id, 0是顶级
parentId?: number;
// 菜单名称
name?: string;
// 类型
type?: string;
// 菜单值
key?: string;
// 用户ID
userId?: number;
// 排序(数字越小越靠前)
sortNumber?: number;
// 备注
comments?: string;
// 状态, 0正常, 1冻结
status?: number;
// 租户id
tenantId?: number;
// 创建时间
createTime?: string;
}
/**
* 小程序端菜单搜索条件
*/
export interface MpOfficialMenuParam extends PageParam {
id?: number;
keywords?: string;
}

61
src/api/index.ts Normal file
View File

@@ -0,0 +1,61 @@
/**
* 接口统一返回结果
*/
export interface ApiResult<T> {
// 状态码
code: number;
// 状态信息
message?: string;
// 返回数据
data?: T;
}
/**
* 分页查询统一结果
*/
export interface PageResult<T> {
// 返回数据
list: T[];
// 总数量
count: number;
}
/**
* 分页查询基本参数
*/
export interface PageParam {
// 第几页
page?: number;
// 每页多少条
limit?: number;
// 排序字段
sort?: string;
sortNum?: string;
// 排序方式, asc升序, desc降序
order?: string;
// 租户ID
tenantId?: number;
// 企业ID
companyId?: number;
// 商户ID
merchantId?: number;
merchantName?: string;
categoryIds?: any;
// 商品分类
categoryId?: number;
categoryName?: string;
// 搜素关键词
keywords?: string;
// 起始时间
createTimeStart?: string;
// 结束时间
createTimeEnd?: string;
timeStart?: number;
timeEnd?: number;
isExpireTime?: number;
showSoldStatus?: boolean;
dateTime?: string;
lang?: string;
model?: string;
BaseUrl?: string;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

116
src/api/layout/index.ts Normal file
View File

@@ -0,0 +1,116 @@
import request from '@/utils/request';
import type { ApiResult } from '@/api/index';
import type { User } from '@/api/system/user/model';
import type { UpdatePasswordParam } from './model';
import type {CmsWebsite} from "@/api/cms/cmsWebsite/model";
import {SERVER_API_URL} from "@/utils/server";
/**
* 获取网站信息
*/
export async function getShopInfo() {
const res = await request.get<ApiResult<CmsWebsite>>(
'/shop/getShopInfo'
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 获取当前登录的用户信息、菜单、权限、角色
*/
export async function getUserInfo(): Promise<User> {
const res = await request.get<ApiResult<User>>(SERVER_API_URL + '/auth/user');
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
export async function updateUserInfo(data: User): Promise<User> {
const res = await request.put<ApiResult<unknown>>(
SERVER_API_URL + '/auth/user',
data
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 获取服务器时间(实时)
* @return
*/
export async function getServerTime() {
const res = await request.get<ApiResult<any>>(
'/cms/website/getServerTime'
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 获取未来7天的日期
* @return
*/
export async function getNext7day() {
const res = await request.get<ApiResult<any>>(
'/cms/website/getNext7day'
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 向子模块传递token
* @param url
*/
export async function transferToken(url: string): Promise<string> {
const res = await request.get<ApiResult<unknown>>(url);
return Promise.reject(new Error(res.message));
}
/**
* 修改当前登录的用户密码
*/
export async function updatePassword(
data: UpdatePasswordParam
): Promise<string> {
const res = await request.put<ApiResult<unknown>>(
'/auth/password',
data
);
if (res.code === 0) {
return res.message ?? '修改成功';
}
return Promise.reject(new Error(res.message));
}
/**
* 获取微信小程序登录凭证
*/
export async function getWxOpenId(data: any) {
const res = await request.post<ApiResult<any>>(SERVER_API_URL + '/wx-login/getWxOpenId',data);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
// 获取微信openId
export async function loginByOpenId(data: any) {
const res = await request.post<ApiResult<any>>(SERVER_API_URL + '/wx-login/loginByOpenId', data);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,29 @@
/**
* 首页布局样式
*/
export interface Layout {
// 内容区域的宽度
width?: string;
// 文字颜色
color?: string;
// 高亮颜色
hover?: string;
// 背景颜色
backgroundColor?: string;
headerStyle?: any;
siteNameStyle?: any;
showBanner?: boolean;
// 背景图片
banner?: string;
}
/**
* 修改密码参数
*/
export interface UpdatePasswordParam {
// 新密码
password: string;
// 原始密码
oldPassword: string;
}

View File

@@ -0,0 +1,75 @@
import request from '@/utils/request';
import type { ApiResult } from '@/api';
import type {
LoginParam,
LoginResult,
CaptchaResult,
SmsCaptchaResult
} from './model';
import {saveStorageByLoginUser, SERVER_API_URL} from "@/utils/server";
import { isUserDisabled } from '@/utils/auth';
/**
* 账号密码登录
*/
export async function login(data: LoginParam) {
const res = await request.post<ApiResult<LoginResult>>(
SERVER_API_URL + '/login',
data
);
if (res.code === 0) {
if (res.data?.user && res.data?.access_token) {
if (isUserDisabled(res.data.user)) {
return Promise.reject(new Error('您的账号已被禁用,请联系管理员'));
}
saveStorageByLoginUser(res.data.access_token, res.data.user)
}
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 获取验证码
*/
export async function getCaptcha() {
const res = await request.get<ApiResult<CaptchaResult>>(
SERVER_API_URL + '/captcha',
{}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
export async function loginBySms(data: LoginParam) {
const res = await request.post<ApiResult<LoginResult>>(
SERVER_API_URL + '/loginBySms',
data
);
if (res.code === 0) {
if(res.data?.user){
if (isUserDisabled(res.data.user)) {
return Promise.reject(new Error('您的账号已被禁用,请联系管理员'));
}
saveStorageByLoginUser(`${res.data?.access_token}`, res.data?.user)
}
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 发送短信验证码
*/
export async function sendSmsCaptcha(data: LoginParam) {
const res = await request.post<ApiResult<SmsCaptchaResult>>(
SERVER_API_URL + '/sendSmsCaptcha',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}

View File

@@ -0,0 +1,52 @@
import type { User } from '@/api/system/user/model';
/**
* 登录参数
*/
export interface LoginParam {
// 账号
username?: string;
// 密码
password?: string;
// 租户id
tenantId?: number;
// 是否记住密码
remember?: boolean;
// 手机号码
phone?: string;
// 短信验证码
code?: string;
// 图形验证码Key
captchaKey?: string;
// 图形验证码文本
captchaText?: string;
}
/**
* 登录返回结果
*/
export interface LoginResult {
// token
access_token?: string;
// 用户信息
user?: User;
}
/**
* 图形验证码返回结果
*/
export interface CaptchaResult {
// 验证码Key
key?: string;
// 图形验证码base64数据
base64: string;
// 验证码文本
text: string;
}
/**
* 短信验证码返回结果
*/
export interface SmsCaptchaResult {
// 验证码文本
text: string;
}

View File

@@ -0,0 +1,244 @@
import request from '@/utils/request';
import type { ApiResult } from '@/api';
import Taro from '@tarojs/taro';
import {SERVER_API_URL} from "@/utils/server";
import {getUserInfo} from "@/api/layout";
/**
* 扫码登录相关接口
*/
// 生成扫码token请求参数
export interface GenerateQRTokenParam {
// 客户端类型web, app, wechat
clientType?: string;
// 设备信息
deviceInfo?: string;
// 过期时间(分钟)
expireMinutes?: number;
}
// 生成扫码token响应
export interface GenerateQRTokenResult {
// 扫码token
token: string;
// 二维码内容通常是包含token的URL或JSON
qrContent: string;
// 过期时间戳
expireTime: number;
// 二维码图片URL可选
qrImageUrl?: string;
}
// 扫码状态枚举
export enum QRLoginStatus {
PENDING = 'pending', // 等待扫码
SCANNED = 'scanned', // 已扫码,等待确认
CONFIRMED = 'confirmed', // 已确认登录
EXPIRED = 'expired', // 已过期
CANCELLED = 'cancelled' // 已取消
}
// 检查扫码状态响应
export interface QRLoginStatusResult {
// 当前状态
status: QRLoginStatus;
// 状态描述
message?: string;
// 如果已确认登录返回JWT token
accessToken?: string;
// 用户信息
userInfo?: {
userId: number;
nickname?: string;
avatar?: string;
phone?: string;
};
// 剩余有效时间(秒)
remainingTime?: number;
}
// 确认登录请求参数
export interface ConfirmLoginParam {
// 扫码token
token: string;
// 用户ID
userId: number;
// 登录平台web, app, wechat
platform?: string;
// 微信用户信息当platform为wechat时
wechatInfo?: {
openid?: string;
unionid?: string;
nickname?: string;
avatar?: string;
gender?: string;
};
// 设备信息
deviceInfo?: string;
}
// 确认登录响应
export interface ConfirmLoginResult {
// 是否成功
success: boolean;
// 消息
message: string;
// 登录用户信息
userInfo?: {
userId: number;
nickname?: string;
avatar?: string;
phone?: string;
};
}
/**
* 生成扫码登录token
*/
export async function generateQRToken(data?: GenerateQRTokenParam) {
const res = await request.post<ApiResult<GenerateQRTokenResult>>(
SERVER_API_URL + '/qr-login/generate',
{
clientType: 'wechat',
expireMinutes: 5,
...data
}
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 检查扫码登录状态
*/
export async function checkQRLoginStatus(token: string) {
const res = await request.get<ApiResult<QRLoginStatusResult>>(
SERVER_API_URL + `/qr-login/status/${token}`
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 确认扫码登录(通用接口)
*/
export async function confirmQRLogin(data: ConfirmLoginParam) {
const res = await request.post<ApiResult<ConfirmLoginResult>>(
SERVER_API_URL + '/qr-login/confirm',
data
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 微信小程序扫码登录确认(便捷接口)
*/
export async function confirmWechatQRLogin(token: string, userId: number) {
try {
// 获取微信用户信息
const userInfo = await getUserInfo();
const data: ConfirmLoginParam = {
token,
userId,
platform: 'wechat',
wechatInfo: {
nickname: userInfo?.nickname,
avatar: userInfo?.avatar,
gender: userInfo?.sex
},
deviceInfo: await getDeviceInfo()
};
const res = await request.post<ApiResult<any>>(
SERVER_API_URL + '/qr-login/confirm',
data
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
} catch (error: any) {
return Promise.reject(new Error(error.message || '确认登录失败'));
}
}
/**
* 获取设备信息
*/
async function getDeviceInfo() {
return new Promise<string>((resolve) => {
Taro.getSystemInfo({
success: (res) => {
const deviceInfo = {
platform: res.platform,
system: res.system,
version: res.version,
model: res.model,
brand: res.brand,
screenWidth: res.screenWidth,
screenHeight: res.screenHeight
};
resolve(JSON.stringify(deviceInfo));
},
fail: () => {
resolve('unknown');
}
});
});
}
/**
* 解析二维码内容提取token
*/
export function parseQRContent(qrContent: string): string | null {
try {
// 尝试解析JSON格式
if (qrContent.startsWith('{')) {
const parsed = JSON.parse(qrContent);
return parsed.token || parsed.qrCodeKey || null;
}
// 尝试解析URL格式
if (qrContent.includes('http')) {
const url = new URL(qrContent);
// 支持多种参数名
return url.searchParams.get('token') ||
url.searchParams.get('qrCodeKey') ||
url.searchParams.get('qr_code_key') ||
null;
}
// 尝试解析简单的key=value格式
if (qrContent.includes('=')) {
const params = new URLSearchParams(qrContent);
return params.get('token') ||
params.get('qrCodeKey') ||
params.get('qr_code_key') ||
null;
}
// 如果是以qr-login:开头的格式
if (qrContent.startsWith('qr-login:')) {
return qrContent.replace('qr-login:', '');
}
// 直接返回内容作为token如果是32位以上的字符串
if (qrContent.length >= 32) {
return qrContent;
}
return null;
} catch (error) {
console.error('解析二维码内容失败:', error);
return null;
}
}

View File

@@ -0,0 +1,127 @@
import request from '@/utils/request';
import type { ApiResult } from '@/api';
import { SERVER_API_URL } from '@/utils/server';
/**
* 微信小程序登录相关接口
*/
// 微信登录请求参数
export interface WxLoginParam {
// 微信登录凭证wx.login() 获取)
code: string;
// 租户ID
tenantId?: number;
}
// 微信登录用户信息
export interface WxLoginUserInfo {
userId: number;
username?: string;
nickname?: string;
avatar?: string;
phone?: string;
openid?: string;
unionid?: string;
tenantId: number;
}
// 微信登录结果
export interface WxLoginResult {
// JWT 访问令牌
access_token?: string;
// 用户信息
user?: WxLoginUserInfo;
// 租户ID
tenantId?: number;
// 登录消息
message?: string;
// 用户ID
userId?: number;
}
/**
* 微信小程序登录(通过 openid
*
* 流程:
* 1. 调用 wx.login() 获取 code
* 2. 用 code 调用此接口
* 3. 后端用 code 换取 openid查库返回用户信息
* 4. 如果用户存在,返回登录 token
* 5. 如果用户不存在,返回 "用户未注册" + openid
*/
export async function loginByOpenId(data: WxLoginParam): Promise<{
success: boolean;
message: string;
data?: WxLoginResult;
openid?: string;
}> {
const res = await request.post<ApiResult<WxLoginResult>>(
SERVER_API_URL + '/wx-login/loginByOpenId',
data
);
console.log('[WxLogin] loginByOpenId 响应:', res);
// 成功:用户已注册
if ((res.code === 0 || res.code === 200) && res.data) {
return {
success: true,
message: res.message || '登录成功',
data: res.data
};
}
// 失败:用户未注册或登录失败
// 后端返回 "用户未注册" 时data 字段是 openid
if (res.message === '用户未注册' || res.message?.includes('用户未注册')) {
return {
success: false,
message: '用户未注册',
openid: res.data as unknown as string
};
}
return {
success: false,
message: res.message || '登录失败'
};
}
/**
* 获取微信 OpenId仅获取不登录
* 注意:后端 /wx-login/getOpenId 返回的是 LoginResult { access_token, user }
* 真正的 openid 在 user.openid 里
*/
export async function getOpenId(code: string): Promise<{
success: boolean;
openid?: string;
unionid?: string;
session_key?: string;
message?: string;
access_token?: string;
user?: WxLoginUserInfo;
}> {
const res = await request.post<ApiResult<WxLoginResult>>(
SERVER_API_URL + '/wx-login/getOpenId',
{ code }
);
console.log('[WxLogin] getOpenId 响应:', res);
if ((res.code === 0 || res.code === 200) && res.data) {
return {
success: true,
openid: res.data.user?.openid,
unionid: res.data.user?.unionid,
session_key: res.data.user?.session_key,
access_token: res.data.access_token,
user: res.data.user
};
}
return {
success: false,
message: res.message || '获取 OpenId 失败'
};
}

23
src/api/share.ts Normal file
View File

@@ -0,0 +1,23 @@
import { generateMiniProgramCode } from '@/api/shop/shopInvite'
/**
* 生成「分享海报」用的小程序码(二维码)图片地址。
*
* - scene 复用现有 uid_${inviterId} 约定,与邀请裂变逻辑一致;
* - page 指向被分享的页面(小程序码扫码后落地页)。
*
* 注意:当前后端 /wx-login/getOrderQRCodeUnlimited/{scene} 仅消费 scene
* 若希望扫码后直达指定页面而非默认页,需后端读取并转发 page 参数。
*
* @param page 被分享页路径,如 pages/shop/product-detail
* @param inviterId 当前登录用户 id用于裂变归因未登录可省略
*/
export function generateShareCode(page: string, inviterId?: number | string) {
const scene = inviterId ? `uid_${inviterId}` : 'share'
return generateMiniProgramCode({
page,
scene,
width: 200,
envVersion: 'release',
})
}

View File

@@ -0,0 +1,110 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
import type {
ShopActivity,
ShopActivityParam,
ActivitySignUpParams,
ActivityStats,
} from './model'
import { normalizeActivity } from './model'
export type { ShopActivity, ActivityStatus, ActivityType } from './model'
/**
* 分页查询活动
*/
export async function pageShopActivity(params: ShopActivityParam) {
const res = await request.get<ApiResult<PageResult<ShopActivity>>>(
'/shop/shop-activity/page',
params
)
if (res.code === 0 && res.data) {
return {
...res.data,
list: (res.data.list || []).map(normalizeActivity),
}
}
return Promise.reject(new Error(res.message))
}
/**
* 查询活动列表
*/
export async function listShopActivity(params?: ShopActivityParam) {
const res = await request.get<ApiResult<ShopActivity[]>>(
'/shop/shop-activity',
params
)
if (res.code === 0 && res.data) {
return res.data.map(normalizeActivity)
}
return Promise.reject(new Error(res.message))
}
/**
* 根据ID查询活动
*/
export async function getShopActivity(id: number) {
const res = await request.get<ApiResult<ShopActivity>>(
'/shop/shop-activity/' + id
)
if (res.code === 0 && res.data) {
return normalizeActivity(res.data)
}
return Promise.reject(new Error(res.message))
}
/**
* 报名活动
*/
export async function signUpActivity(params: ActivitySignUpParams) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-activity/sign-up',
params
)
if (res.code === 0) {
return res.message
}
return Promise.reject(new Error(res.message))
}
/**
* 取消报名
*/
export async function cancelSignUpActivity(activityId: number) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-activity/cancel-sign-up',
{ activityId }
)
if (res.code === 0) {
return res.message
}
return Promise.reject(new Error(res.message))
}
/**
* 获取活动报名状态
*/
export async function getSignUpStatus(activityId: number) {
const res = await request.get<ApiResult<{ signedUp: boolean }>>(
'/shop/shop-activity/sign-up-status',
{ activityId }
)
if (res.code === 0 && res.data) {
return res.data
}
return Promise.reject(new Error(res.message))
}
/**
* 获取活动统计
*/
export async function getActivityStats() {
const res = await request.get<ApiResult<ActivityStats>>(
'/shop/shop-activity/stats'
)
if (res.code === 0 && res.data) {
return res.data
}
return Promise.reject(new Error(res.message))
}

View File

@@ -0,0 +1,89 @@
/**
* 活动模型
*/
// 活动类型(前端语义化)
export type ActivityType = 'discount' | 'full_reduction' | 'seckill' | 'group_buy' | 'flash_sale'
// 活动状态(前端语义化)
export type ActivityStatus = 'upcoming' | 'ongoing' | 'ended' | 'cancelled'
// 活动数据(与后端字段对齐)
export interface ShopActivity {
id: number
name: string
image: string
banner?: string
startTime: string
endTime: string
/** 后端返回整数: 0=未开始 1=进行中 2=已结束,前端通过 normalizeActivity 转为语义化字符串 */
status: ActivityStatus | number
/** 后端返回整数: 1=满减 2=折扣 3=秒杀 4=拼团 */
type: ActivityType | number
typeName?: string
description: string
participants?: number
maxParticipants?: number
discountRate?: number
reductionAmount?: number
minAmount?: number
rules?: string
tenantId?: number
createTime: string
updateTime?: string
}
// 活动查询参数
export interface ShopActivityParam {
page?: number
limit?: number
status?: number | ActivityStatus
type?: number | ActivityType
keywords?: string
}
// 活动报名参数
export interface ActivitySignUpParams {
activityId: number
userId?: number
contactPhone?: string
remark?: string
}
// 活动统计
export interface ActivityStats {
total: number
ongoing: number
upcoming: number
ended: number
totalParticipants: number
}
// 后端整数状态 → 前端语义化状态
export function normalizeActivityStatus(status: number | ActivityStatus): ActivityStatus {
if (typeof status === 'string') return status
const map: Record<number, ActivityStatus> = { 0: 'upcoming', 1: 'ongoing', 2: 'ended' }
return map[status] ?? 'ended'
}
// 后端整数类型 → 前端语义化类型
export function normalizeActivityType(type: number | ActivityType): ActivityType {
if (typeof type === 'string') return type
const map: Record<number, ActivityType> = {
1: 'full_reduction',
2: 'discount',
3: 'seckill',
4: 'group_buy',
}
return map[type] ?? 'discount'
}
// 规范化活动对象(处理后端整数字段)
export function normalizeActivity(a: ShopActivity): ShopActivity & { status: ActivityStatus; type: ActivityType } {
return {
...a,
participants: a.participants ?? 0,
status: normalizeActivityStatus(a.status as number),
type: normalizeActivityType(a.type as number),
}
}

View File

@@ -0,0 +1,154 @@
import request from '@/utils/request'
import type { ApiResult, PageResult } from '@/api'
// 售后类型
export type AfterSaleType = 'refund' | 'return' | 'exchange' | 'repair'
// 售后状态
export type AfterSaleStatus =
| 'pending' // 待审核
| 'approved' // 已同意
| 'rejected' // 已拒绝
| 'processing' // 处理中
| 'completed' // 已完成
| 'cancelled' // 已取消
// 售后进度记录
export interface ProgressRecord {
id: string
time: string
status: string
description: string
operator?: string
remark?: string
}
// 售后详情
export interface AfterSaleDetail {
id: string
orderId: string
orderNo: string
goodsName?: string
type: AfterSaleType
status: AfterSaleStatus
reason: string
description: string
amount: number
applyTime: string
processTime?: string
completeTime?: string
rejectReason?: string
contactPhone?: string
evidenceImages: string[]
progressRecords: ProgressRecord[]
}
// 售后申请参数
export interface AfterSaleApplyParams {
orderId: string
type: AfterSaleType
reason: string
description?: string
amount?: number
contactPhone?: string
evidenceImages?: string[]
goodsItems?: Array<{ goodsId: string; quantity: number }>
}
// 售后列表查询参数
export interface AfterSaleListParams {
page?: number
pageSize?: number
status?: AfterSaleStatus
type?: AfterSaleType
}
// 售后类型映射
export const AFTER_SALE_TYPE_MAP: Record<AfterSaleType, string> = {
refund: '退款',
return: '退货',
exchange: '换货',
repair: '维修',
}
// 售后状态映射
export const AFTER_SALE_STATUS_MAP: Record<AfterSaleStatus, string> = {
pending: '待审核',
approved: '已同意',
rejected: '已拒绝',
processing: '处理中',
completed: '已完成',
cancelled: '已取消',
}
// 格式化售后状态
export const formatAfterSaleStatus = (status: AfterSaleStatus): {
text: string
color: string
icon: string
} => {
const statusMap: Record<AfterSaleStatus, { text: string; color: string; icon: string }> = {
pending: { text: '待审核', color: 'text-orange-500', icon: '⏳' },
approved: { text: '已同意', color: 'text-green-500', icon: '✅' },
rejected: { text: '已拒绝', color: 'text-red-500', icon: '❌' },
processing: { text: '处理中', color: 'text-blue-500', icon: '🔄' },
completed: { text: '已完成', color: 'text-green-500', icon: '✅' },
cancelled: { text: '已取消', color: 'text-gray-400', icon: '⭕' },
}
return statusMap[status] || { text: status, color: 'text-gray-400', icon: '📋' }
}
/**
* 申请售后
*/
export async function applyAfterSale(data: AfterSaleApplyParams) {
const res = await request.post<ApiResult<AfterSaleDetail>>(
'/shop/shop-after-sale/apply',
data
)
if (res.code === 0) {
return res.data
}
return Promise.reject(new Error(res.message))
}
/**
* 分页查询售后列表
*/
export async function pageAfterSaleList(params: AfterSaleListParams) {
const res = await request.get<ApiResult<PageResult<AfterSaleDetail>>>(
'/shop/shop-after-sale/page',
params
)
if (res.code === 0) {
return res.data
}
return Promise.reject(new Error(res.message))
}
/**
* 查询售后详情
*/
export async function getAfterSaleDetail(id: string) {
const res = await request.get<ApiResult<AfterSaleDetail>>(
'/shop/shop-after-sale/' + id
)
if (res.code === 0 && res.data) {
return res.data
}
return Promise.reject(new Error(res.message))
}
/**
* 撤销售后申请
*/
export async function cancelAfterSale(id: string) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-after-sale/cancel',
{ id }
)
if (res.code === 0) {
return res.message
}
return Promise.reject(new Error(res.message))
}

View File

@@ -0,0 +1,101 @@
import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { ShopArticle, ShopArticleParam } from './model';
/**
* 分页查询商品文章
*/
export async function pageShopArticle(params: ShopArticleParam) {
const res = await request.get<ApiResult<PageResult<ShopArticle>>>(
'/shop/shop-article/page',
params
);
if (res.code === 0) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 查询商品文章列表
*/
export async function listShopArticle(params?: ShopArticleParam) {
const res = await request.get<ApiResult<ShopArticle[]>>(
'/shop/shop-article',
params
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}
/**
* 添加商品文章
*/
export async function addShopArticle(data: ShopArticle) {
const res = await request.post<ApiResult<unknown>>(
'/shop/shop-article',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 修改商品文章
*/
export async function updateShopArticle(data: ShopArticle) {
const res = await request.put<ApiResult<unknown>>(
'/shop/shop-article',
data
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 删除商品文章
*/
export async function removeShopArticle(id?: number) {
const res = await request.del<ApiResult<unknown>>(
'/shop/shop-article/' + id
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 批量删除商品文章
*/
export async function removeBatchShopArticle(data: (number | undefined)[]) {
const res = await request.del<ApiResult<unknown>>(
'/shop/shop-article/batch',
{
data
}
);
if (res.code === 0) {
return res.message;
}
return Promise.reject(new Error(res.message));
}
/**
* 根据id查询商品文章
*/
export async function getShopArticle(id: number) {
const res = await request.get<ApiResult<ShopArticle>>(
'/shop/shop-article/' + id
);
if (res.code === 0 && res.data) {
return res.data;
}
return Promise.reject(new Error(res.message));
}

Some files were not shown because too many files have changed in this diff Show More