diff --git a/.DS_Store b/.DS_Store index d38185d..4085ce8 100644 --- a/.DS_Store +++ b/.DS_Store diff --git a/.gitignore b/.gitignore index 451df8d..66b37d5 100644 --- a/.gitignore +++ b/.gitignore @@ -272,4 +272,7 @@ __pycache__/ .config/ admin-web *.rar -*.zip \ No newline at end of file +*.zip + +# Cursor IDE files +.cursor/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a442983 --- /dev/null +++ b/README.md @@ -0,0 +1,374 @@ +# 绿纤ERP管理系统 + +## 项目简介 + +绿纤ERP管理系统是一个基于现代化技术栈开发的企业资源规划系统,专为绿纤行业量身定制。系统采用前后端分离架构,提供完整的生产、销售、库存、财务等业务管理功能。 + +## 技术栈 + +### 后端技术 +- **.NET Core 3.1/5.0** - 跨平台Web框架 +- **SqlSugar** - 轻量级ORM框架 +- **MySQL** - 关系型数据库 +- **JWT** - 身份认证 +- **Serilog** - 结构化日志 +- **Swagger** - API文档 + +### 前端技术 +- **Vue 2.6** - 渐进式JavaScript框架 +- **Element UI** - 企业级UI组件库 +- **Vuex** - 状态管理 +- **Vue Router** - 路由管理 +- **Axios** - HTTP客户端 +- **SCSS** - CSS预处理器 + +## 项目结构 + +``` +lvqianmeiye_ERP/ +├── netcore/ # 后端.NET Core项目 +│ └── src/ +│ ├── Application/ # 应用层 +│ ├── Infrastructure/ # 基础设施层 +│ └── Modularity/ # 业务模块层 +│ ├── System/ # 系统管理模块 +│ ├── Extend/ # 🎯 核心业务模块(绿纤ERP业务逻辑) +│ │ ├── NCC.Extend/ # 业务服务层 +│ │ ├── NCC.Extend.Entitys/ # 实体模型层 +│ │ └── NCC.Extend.Interfaces/ # 接口定义层 +│ ├── OAuth/ # 身份认证模块 +│ ├── Message/ # 消息中心模块 +│ ├── Order/ # 订单管理模块 +│ ├── VisualDev/ # 可视化开发模块 +│ └── Tenant/ # 多租户支持模块 +├── antis-ncc-admin/ # 前端Vue项目 +│ ├── src/ +│ │ ├── api/ # API接口 +│ │ ├── components/ # 公共组件 +│ │ ├── views/ # 页面视图 +│ │ │ ├── lqBmzb/ # 部门管理页面 +│ │ │ ├── lqCpxx/ # 产品信息页面 +│ │ │ ├── lqHygl/ # 会员管理页面 +│ │ │ └── ... # 其他业务页面 +│ │ ├── router/ # 路由配置 +│ │ └── store/ # 状态管理 +│ ├── package.json # 前端依赖配置 +│ └── vue.config.js # Vue构建配置 +└── html/ # 静态资源 +``` + +## 🎯 核心业务模块说明 + +**Extend模块**是系统的核心业务模块,包含绿纤ERP的所有业务逻辑。该模块采用三层架构设计: + +### NCC.Extend(业务服务层) +包含所有业务服务的具体实现,按功能分类: + +#### 📋 基础管理类 +- `LqBmzbService` - 部门管理服务 +- `LqCpxxService` - 产品信息管理服务 +- `LqHyglService` - 会员管理服务 +- `LqKhxxService` - 客户信息管理服务 +- `LqRyzlService` - 人员资料管理服务 + +#### 🏭 生产管理类 +- `LqJsfaService` - 工艺方案管理服务 +- `LqSbtjbService` - 设备统计管理服务 +- `LqYcsdJsjService` - 技术数据管理服务 +- `LqYcsdJjlftjsService` - 技术方案管理服务 +- `LqYcsdMdlbjhsxxService` - 模具管理服务 + +#### 💰 销售管理类 +- `LqXhHyhkService` - 销售回款管理服务 +- `LqXhmxbService` - 销售明细管理服务 +- `LqTkXscService` - 提成管理服务 +- `LqTkjlbService` - 提成记录管理服务 + +#### 📦 库存管理类 +- `LqKqhzbService` - 库存汇总管理服务 +- `LqLssjService` - 历史数据管理服务 +- `LqYjmxbService` - 原料明细管理服务 + +#### 📊 财务管理类 +- `LqSkzhService` - 收款账户管理服务 +- `LqHzfService` - 汇总费用管理服务 +- `LqJdqdService` - 季度清单管理服务 + +#### 🔧 系统工具类 +- `EmailService` - 邮件服务 +- `DocumentService` - 文档管理服务 +- `BigDataService` - 大数据分析服务 +- `WorkLogService` - 工作日志服务 + +### NCC.Extend.Entitys(实体模型层) +- **Entity/** - 数据库实体模型(66个实体) +- **Dto/** - 数据传输对象(304个DTO) +- **Mapper/** - 对象映射配置(50个映射器) +- **Model/** - 业务模型类 + +### NCC.Extend.Interfaces(接口定义层) +- 定义所有业务服务的接口契约 +- 支持依赖注入和单元测试 +- 提供清晰的业务边界 + +## 环境要求 + +### 开发环境 +- **Node.js**: 16.20.2 (必须使用此版本) +- **.NET Core SDK**: 3.1 或 5.0 +- **MySQL**: 5.7 或 8.0 +- **Visual Studio 2019/2022** 或 **VS Code** + +### 浏览器支持 +- Chrome 70+ +- Firefox 65+ +- Safari 12+ +- Edge 79+ + +## 快速开始 + +### 1. 克隆项目 +```bash +git clone [项目地址] +cd lvqianmeiye_ERP +``` + +### 2. 后端启动 + +#### 方式一:Visual Studio +1. 打开 `netcore/smart.agriculture.platform.NET.sln` +2. 设置 `NCC.API` 为启动项目 +3. 按 F5 运行 + +#### 方式二:命令行 +```bash +cd netcore/src/Application/NCC.API +dotnet restore +dotnet run +``` + +### 3. 前端启动 + +```bash +cd antis-ncc-admin + +# 安装依赖 +npm install + +# 启动开发服务器 +npm run dev +``` + +### 4. 访问系统 +- 前端地址:http://localhost:3000 +- 后端API:http://localhost:5000 +- API文档:http://localhost:5000/antis.doc + +## 默认账号 + +- **管理员账号**:admin +- **默认密码**:123456 + +## 主要功能模块 + +> 💡 **说明**:所有业务功能的核心代码都位于 `netcore/src/Modularity/Extend/` 模块中 + +### 📋 基础管理模块 +- **部门管理** (`LqBmzbService`) - 组织架构管理,部门分类维护 +- **产品信息** (`LqCpxxService`) - 产品档案管理,产品分类维护 +- **会员管理** (`LqHyglService`) - 客户信息管理,会员等级维护 +- **客户信息** (`LqKhxxService`) - 客户档案管理,客户关系维护 +- **人员资料** (`LqRyzlService`) - 员工信息管理,人员档案维护 + +### 🏭 生产管理模块 +- **工艺方案** (`LqJsfaService`) - 生产工艺配置,工艺流程管理 +- **设备统计** (`LqSbtjbService`) - 设备使用情况统计,设备维护管理 +- **技术数据** (`LqYcsdJsjService`) - 技术参数管理,工艺数据维护 +- **技术方案** (`LqYcsdJjlftjsService`) - 技术方案管理,工艺优化 +- **模具管理** (`LqYcsdMdlbjhsxxService`) - 模具档案管理,模具维护 + +### 💰 销售管理模块 +- **销售回款** (`LqXhHyhkService`) - 销售回款管理,资金回笼跟踪 +- **销售明细** (`LqXhmxbService`) - 销售明细管理,销售数据分析 +- **提成管理** (`LqTkXscService`) - 销售提成计算,提成规则维护 +- **提成记录** (`LqTkjlbService`) - 提成记录管理,提成发放跟踪 + +### 📦 库存管理模块 +- **库存汇总** (`LqKqhzbService`) - 库存数据分析,库存统计报表 +- **历史数据** (`LqLssjService`) - 历史数据管理,数据归档 +- **原料明细** (`LqYjmxbService`) - 原料库存管理,原料使用跟踪 + +### 📊 财务管理模块 +- **收款账户** (`LqSkzhService`) - 收款账户管理,资金账户维护 +- **汇总费用** (`LqHzfService`) - 费用汇总管理,成本分析 +- **季度清单** (`LqJdqdService`) - 季度财务清单,财务报告 + +### 🔧 系统工具模块 +- **邮件服务** (`EmailService`) - 邮件发送,通知提醒 +- **文档管理** (`DocumentService`) - 文档存储,文件管理 +- **大数据分析** (`BigDataService`) - 数据分析,报表生成 +- **工作日志** (`WorkLogService`) - 工作日志记录,操作跟踪 + +### ⚙️ 系统管理模块(位于System模块) +- **用户管理** - 系统用户维护,用户权限管理 +- **角色权限** - 权限分配管理,角色权限配置 +- **系统配置** - 系统参数设置,基础配置维护 +- **日志管理** - 操作日志查看,系统日志分析 + +## 开发指南 + +### 🎯 核心业务开发(Extend模块) + +#### 添加新的业务服务 +1. **创建实体模型** (`NCC.Extend.Entitys/Entity/`) + ```csharp + [SugarTable("lq_新表名")] + [Tenant(ClaimConst.TENANT_ID)] + public class Lq新实体Entity + { + [SugarColumn(ColumnName = "F_Id", IsPrimaryKey = true)] + public string Id { get; set; } + // 其他字段... + } + ``` + +2. **创建DTO对象** (`NCC.Extend.Entitys/Dto/`) + - `Lq新实体ListQueryInput` - 列表查询输入 + - `Lq新实体CrInput` - 创建输入 + - `Lq新实体UpInput` - 更新输入 + - `Lq新实体InfoOutput` - 详情输出 + - `Lq新实体ListOutput` - 列表输出 + +3. **创建接口定义** (`NCC.Extend.Interfaces/`) + ```csharp + public interface ILq新实体Service : ITransient + { + Task GetInfo(string id); + Task GetList(Lq新实体ListQueryInput input); + Task Create(Lq新实体CrInput input); + Task Update(string id, Lq新实体UpInput input); + Task Delete(string id); + } + ``` + +4. **实现业务服务** (`NCC.Extend/`) + ```csharp + [ApiDescriptionSettings(Tag = "Extend", Name = "Lq新实体", Order = 200)] + [Route("api/Extend/[controller]")] + public class Lq新实体Service : ILq新实体Service, IDynamicApiController, ITransient + { + // 服务实现... + } + ``` + +#### 前端页面开发 +1. **创建页面组件** (`antis-ncc-admin/src/views/lq新模块/`) + - `index.vue` - 列表页面 + - `Form.vue` - 表单页面 + - `ExportBox.vue` - 导出组件 + +2. **添加API接口** (`antis-ncc-admin/src/api/extend/`) + ```javascript + export function getLq新实体List(data) { + return request({ + url: '/api/Extend/Lq新实体', + method: 'GET', + data + }) + } + ``` + +### 前端开发 +```bash +# 开发模式 +npm run dev + +# 构建生产版本 +npm run build + +# 代码检查 +npm run lint +``` + +### 后端开发 +```bash +# 还原包 +dotnet restore + +# 编译项目 +dotnet build + +# 运行项目 +dotnet run + +# 发布项目 +dotnet publish -c Release +``` + +## 配置说明 + +### 数据库配置 +修改 `netcore/src/Application/NCC.API/appsettings.json` 中的连接字符串: + +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Database=lqerp;Data Source=localhost;Port=3306;User Id=root;Password=yourpassword;Charset=utf8;" + } +} +``` + +### 前端代理配置 +修改 `antis-ncc-admin/vue.config.js` 中的代理地址: + +```javascript +proxy: { + '/dev': { + target: 'http://localhost:5000', // 后端API地址 + changeOrigin: true, + pathRewrite: { + '^/dev': '' + } + } +} +``` + +## 部署说明 + +### 后端部署 +1. 发布项目:`dotnet publish -c Release` +2. 配置数据库连接字符串 +3. 部署到IIS或Linux服务器 + +### 前端部署 +1. 构建项目:`npm run build` +2. 将 `dist` 目录部署到Web服务器 +3. 配置Nginx或IIS反向代理 + +## 常见问题 + +### Q: 前端启动失败 +A: 确保使用Node.js 16.20.2版本,其他版本可能不兼容 + +### Q: 后端连接数据库失败 +A: 检查数据库连接字符串和MySQL服务状态 + +### Q: 权限验证失败 +A: 检查JWT配置和Token有效期设置 + +### Q: 页面显示异常 +A: 检查浏览器控制台错误信息和网络请求状态 + +## 技术支持 + +如有技术问题,请联系开发团队或查看项目文档。 + +## 版本信息 + +- **当前版本**:v1.0.0 +- **最后更新**:2024年 +- **维护状态**:活跃开发中 + +--- + +**注意**:本项目仅供学习和内部使用,请勿用于商业用途。 diff --git a/analyze_excel.py b/analyze_excel.py new file mode 100644 index 0000000..2a03a64 --- /dev/null +++ b/analyze_excel.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Excel工资核算文件分析工具 +分析工资核算相关的Excel文件,提取字段信息和引用关系 +""" + +import pandas as pd +import os +import re +from pathlib import Path + +def analyze_excel_file(file_path, sheet_name=None): + """分析单个Excel文件""" + try: + # 获取所有工作表名称 + excel_file = pd.ExcelFile(file_path) + sheets = excel_file.sheet_names + + print(f"\n=== 分析文件: {os.path.basename(file_path)} ===") + print(f"工作表数量: {len(sheets)}") + print(f"工作表名称: {sheets}") + + analysis_result = { + 'file_name': os.path.basename(file_path), + 'sheets': {}, + 'all_columns': set(), + 'formulas': [], + 'references': [] + } + + # 分析每个工作表 + for sheet in sheets: + if sheet_name and sheet != sheet_name: + continue + + try: + df = pd.read_excel(file_path, sheet_name=sheet, header=0) + print(f"\n--- 工作表: {sheet} ---") + print(f"行数: {len(df)}") + print(f"列数: {len(df.columns)}") + print(f"列名: {list(df.columns)}") + + # 收集列名 + analysis_result['all_columns'].update(df.columns) + analysis_result['sheets'][sheet] = { + 'rows': len(df), + 'columns': len(df.columns), + 'column_names': list(df.columns), + 'sample_data': df.head(3).to_dict('records') if len(df) > 0 else [] + } + + # 查找公式和引用 + for col in df.columns: + for idx, value in df[col].items(): + if pd.notna(value) and isinstance(value, str): + # 查找Excel公式模式 + formula_patterns = [ + r'=([A-Z]+[0-9]+)', # 单元格引用 + r'=([A-Z]+[0-9]+:[A-Z]+[0-9]+)', # 范围引用 + r'=([A-Z]+[0-9]+\[[^\]]+\])', # 数组引用 + r'=([A-Z]+[0-9]+\$[0-9]+)', # 绝对引用 + r'=([A-Z]+[0-9]+:[A-Z]+[0-9]+\$[0-9]+)', # 绝对范围引用 + ] + + for pattern in formula_patterns: + matches = re.findall(pattern, str(value)) + if matches: + analysis_result['formulas'].append({ + 'sheet': sheet, + 'cell': f"{col}{idx+1}", + 'formula': str(value), + 'references': matches + }) + analysis_result['references'].extend(matches) + + except Exception as e: + print(f"分析工作表 {sheet} 时出错: {e}") + analysis_result['sheets'][sheet] = {'error': str(e)} + + return analysis_result + + except Exception as e: + print(f"分析文件 {file_path} 时出错: {e}") + return None + +def main(): + """主函数""" + base_path = "/Users/mr.wang/代码库/绿纤/lvqianmeiye_ERP/参考资料/工资核算 -7月" + + # 要分析的文件列表 + files_to_analyze = [ + "工资(全字段).xlsx", + "①B-a-26考勤汇总表.xlsx", + "②B-a-17每日早报.xlsx", + "③B-a-③呈现-消耗明细表.xlsx", + "④B-a-25社保统计表.xlsx", + "⑤B-a-12奖励统计表.xlsx", + "B-b-③健康师底薪.xlsx", + "B-b-④健康师提成-金三角顾问.xlsx", + "B-b-⑤其他岗位工资.xlsx", + "B-b-⑤当月数据及门店毛利.xlsx" + ] + + all_results = {} + + print("开始分析工资核算Excel文件...") + print("=" * 60) + + for filename in files_to_analyze: + file_path = os.path.join(base_path, filename) + if os.path.exists(file_path): + result = analyze_excel_file(file_path) + if result: + all_results[filename] = result + else: + print(f"文件不存在: {filename}") + + # 生成分析报告 + generate_report(all_results) + +def generate_report(all_results): + """生成分析报告""" + report_path = "/Users/mr.wang/代码库/绿纤/lvqianmeiye_ERP/工资核算Excel分析报告.md" + + with open(report_path, 'w', encoding='utf-8') as f: + f.write("# 工资核算Excel文件分析报告\n\n") + f.write("## 概述\n\n") + f.write("本报告分析了工资核算相关的Excel文件,提取了字段信息、公式引用关系等关键数据。\n\n") + + # 文件概览 + f.write("## 文件概览\n\n") + f.write("| 文件名 | 工作表数量 | 总列数 | 状态 |\n") + f.write("|--------|------------|--------|------|\n") + + for filename, result in all_results.items(): + if result: + sheet_count = len(result['sheets']) + total_columns = len(result['all_columns']) + f.write(f"| {filename} | {sheet_count} | {total_columns} | ✅ |\n") + else: + f.write(f"| {filename} | - | - | ❌ |\n") + + # 详细分析 + f.write("\n## 详细分析\n\n") + + for filename, result in all_results.items(): + if not result: + continue + + f.write(f"### {filename}\n\n") + + # 工作表信息 + f.write("#### 工作表信息\n\n") + for sheet_name, sheet_info in result['sheets'].items(): + if 'error' in sheet_info: + f.write(f"- **{sheet_name}**: 分析出错 - {sheet_info['error']}\n") + else: + f.write(f"- **{sheet_name}**: {sheet_info['rows']}行 x {sheet_info['columns']}列\n") + f.write(f" - 列名: {', '.join([str(col) for col in sheet_info['column_names']])}\n") + + # 字段统计 + f.write(f"\n#### 字段统计\n\n") + f.write(f"总字段数: {len(result['all_columns'])}\n\n") + f.write("所有字段列表:\n") + for col in sorted(result['all_columns'], key=str): + f.write(f"- {col}\n") + + # 公式引用 + if result['formulas']: + f.write(f"\n#### 公式引用\n\n") + f.write(f"发现 {len(result['formulas'])} 个公式引用:\n\n") + for formula in result['formulas'][:10]: # 只显示前10个 + f.write(f"- **{formula['cell']}** ({formula['sheet']}): {formula['formula']}\n") + f.write(f" - 引用: {', '.join(formula['references'])}\n") + + if len(result['formulas']) > 10: + f.write(f"\n... 还有 {len(result['formulas']) - 10} 个公式\n") + + f.write("\n---\n\n") + + # 字段汇总 + f.write("## 字段汇总\n\n") + all_columns = set() + for result in all_results.values(): + if result: + all_columns.update(result['all_columns']) + + f.write(f"所有文件共发现 {len(all_columns)} 个唯一字段:\n\n") + for col in sorted(all_columns, key=str): + f.write(f"- {col}\n") + + # 引用关系汇总 + f.write("\n## 引用关系汇总\n\n") + all_references = set() + for result in all_results.values(): + if result: + all_references.update(result['references']) + + f.write(f"发现 {len(all_references)} 个唯一引用:\n\n") + for ref in sorted(all_references, key=str): + f.write(f"- {ref}\n") + + print(f"\n分析报告已生成: {report_path}") + +if __name__ == "__main__": + main() diff --git a/analyze_formulas.py b/analyze_formulas.py new file mode 100644 index 0000000..08a3824 --- /dev/null +++ b/analyze_formulas.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Excel公式分析工具 +分析工资核算Excel文件中的公式和引用关系 +""" + +import pandas as pd +import openpyxl +import os +import re +from pathlib import Path + +def extract_formulas_from_excel(file_path): + """从Excel文件中提取所有公式""" + try: + # 使用openpyxl读取Excel文件以获取公式 + workbook = openpyxl.load_workbook(file_path, data_only=False) + + formulas = [] + references = [] + + for sheet_name in workbook.sheetnames: + worksheet = workbook[sheet_name] + + for row in worksheet.iter_rows(): + for cell in row: + if cell.data_type == 'f': # 公式类型 + formula = str(cell.value) + cell_ref = f"{sheet_name}!{cell.coordinate}" + + # 提取公式中的引用 + refs = extract_references_from_formula(formula) + + formulas.append({ + 'file': os.path.basename(file_path), + 'sheet': sheet_name, + 'cell': cell.coordinate, + 'formula': formula, + 'references': refs + }) + + references.extend(refs) + + return formulas, references + + except Exception as e: + print(f"分析文件 {file_path} 时出错: {e}") + return [], [] + +def extract_references_from_formula(formula): + """从公式中提取引用关系""" + references = [] + + # 匹配各种引用模式 + patterns = [ + # XLOOKUP引用模式 + r"XLOOKUP\([^,]+,\s*'([^']+)'!([^,]+),\s*'([^']+)'!([^,]+)", + # VLOOKUP引用模式 + r"VLOOKUP\([^,]+,\s*'([^']+)'!([^,]+)", + # 直接工作表引用 + r"'([^']+)'!([A-Z]+\d+)", + # 工作表范围引用 + r"'([^']+)'!([A-Z]+\d+:[A-Z]+\d+)", + # 简单单元格引用 + r"([A-Z]+\d+)", + # 范围引用 + r"([A-Z]+\d+:[A-Z]+\d+)", + ] + + for pattern in patterns: + matches = re.findall(pattern, formula) + for match in matches: + if isinstance(match, tuple): + if len(match) == 2: + references.append({ + 'type': 'worksheet_reference', + 'file': match[0] if match[0] else None, + 'range': match[1] + }) + elif len(match) == 4: + references.append({ + 'type': 'xlookup_reference', + 'file': match[0], + 'lookup_range': match[1], + 'file2': match[2], + 'return_range': match[3] + }) + else: + references.append({ + 'type': 'cell_reference', + 'range': match + }) + + return references + +def analyze_formula_dependencies(formulas): + """分析公式依赖关系""" + dependencies = {} + + for formula in formulas: + cell_key = f"{formula['file']}!{formula['sheet']}!{formula['cell']}" + dependencies[cell_key] = { + 'formula': formula['formula'], + 'dependencies': formula['references'] + } + + return dependencies + +def generate_formula_report(formulas, references, dependencies): + """生成公式分析报告""" + report_path = "/Users/mr.wang/代码库/绿纤/lvqianmeiye_ERP/Excel公式分析报告.md" + + with open(report_path, 'w', encoding='utf-8') as f: + f.write("# Excel公式分析报告\n\n") + f.write("## 概述\n\n") + f.write("本报告分析了工资核算Excel文件中的公式和引用关系,帮助理解数据计算逻辑。\n\n") + + # 统计信息 + f.write("## 统计信息\n\n") + f.write(f"- 总公式数量: {len(formulas)}\n") + f.write(f"- 总引用数量: {len(references)}\n") + f.write(f"- 涉及文件数量: {len(set(f['file'] for f in formulas))}\n\n") + + # 按文件分组分析 + files = {} + for formula in formulas: + file_name = formula['file'] + if file_name not in files: + files[file_name] = [] + files[file_name].append(formula) + + f.write("## 文件公式分析\n\n") + + for file_name, file_formulas in files.items(): + f.write(f"### {file_name}\n\n") + f.write(f"公式数量: {len(file_formulas)}\n\n") + + # 按工作表分组 + sheets = {} + for formula in file_formulas: + sheet_name = formula['sheet'] + if sheet_name not in sheets: + sheets[sheet_name] = [] + sheets[sheet_name].append(formula) + + for sheet_name, sheet_formulas in sheets.items(): + f.write(f"#### 工作表: {sheet_name}\n\n") + f.write(f"公式数量: {len(sheet_formulas)}\n\n") + + # 显示前10个公式 + for i, formula in enumerate(sheet_formulas[:10]): + f.write(f"**{formula['cell']}**:\n") + f.write(f"```\n{formula['formula']}\n```\n") + + if formula['references']: + f.write("引用关系:\n") + for ref in formula['references']: + if ref['type'] == 'xlookup_reference': + f.write(f"- XLOOKUP: {ref['file']}!{ref['lookup_range']} -> {ref['file2']}!{ref['return_range']}\n") + elif ref['type'] == 'worksheet_reference': + f.write(f"- 工作表引用: {ref['file']}!{ref['range']}\n") + elif ref['type'] == 'cell_reference': + f.write(f"- 单元格引用: {ref['range']}\n") + f.write("\n") + else: + f.write("无外部引用\n\n") + + if len(sheet_formulas) > 10: + f.write(f"... 还有 {len(sheet_formulas) - 10} 个公式\n\n") + + f.write("---\n\n") + + # 引用关系汇总 + f.write("## 引用关系汇总\n\n") + + # 统计引用类型 + ref_types = {} + for ref in references: + ref_type = ref['type'] + if ref_type not in ref_types: + ref_types[ref_type] = 0 + ref_types[ref_type] += 1 + + f.write("### 引用类型统计\n\n") + for ref_type, count in ref_types.items(): + f.write(f"- {ref_type}: {count} 个\n") + f.write("\n") + + # 外部文件引用 + external_refs = {} + for ref in references: + if ref['type'] == 'xlookup_reference' and ref['file']: + file_name = ref['file'] + if file_name not in external_refs: + external_refs[file_name] = [] + external_refs[file_name].append(ref) + + if external_refs: + f.write("### 外部文件引用\n\n") + for file_name, refs in external_refs.items(): + f.write(f"**{file_name}**: {len(refs)} 个引用\n") + for ref in refs[:5]: # 只显示前5个 + f.write(f"- {ref['file']}!{ref['lookup_range']} -> {ref['file2']}!{ref['return_range']}\n") + if len(refs) > 5: + f.write(f"... 还有 {len(refs) - 5} 个引用\n") + f.write("\n") + + # 公式依赖关系图 + f.write("## 公式依赖关系\n\n") + f.write("### 关键公式分析\n\n") + + # 找出包含XLOOKUP的公式 + xlookup_formulas = [f for f in formulas if 'XLOOKUP' in f['formula']] + + if xlookup_formulas: + f.write("#### XLOOKUP公式分析\n\n") + for formula in xlookup_formulas[:10]: + f.write(f"**{formula['file']}!{formula['sheet']}!{formula['cell']}**:\n") + f.write(f"```\n{formula['formula']}\n```\n") + + # 解析XLOOKUP参数 + xlookup_match = re.search(r"XLOOKUP\(([^,]+),\s*'([^']+)'!([^,]+),\s*'([^']+)'!([^,]+)", formula['formula']) + if xlookup_match: + lookup_value = xlookup_match.group(1).strip() + lookup_file = xlookup_match.group(2) + lookup_range = xlookup_match.group(3) + return_file = xlookup_match.group(4) + return_range = xlookup_match.group(5) + + f.write("参数解析:\n") + f.write(f"- 查找值: {lookup_value}\n") + f.write(f"- 查找范围: {lookup_file}!{lookup_range}\n") + f.write(f"- 返回范围: {return_file}!{return_range}\n") + f.write("\n") + + # 数据流分析 + f.write("### 数据流向分析\n\n") + f.write("基于公式分析,数据流向如下:\n\n") + + # 分析数据源文件 + data_sources = set() + for ref in references: + if ref['type'] == 'xlookup_reference' and ref['file']: + data_sources.add(ref['file']) + + f.write("**数据源文件**:\n") + for source in sorted(data_sources): + f.write(f"- {source}\n") + f.write("\n") + + f.write("**数据流向**:\n") + f.write("1. 基础数据从各数据源文件获取\n") + f.write("2. 通过XLOOKUP/VLOOKUP函数进行数据匹配\n") + f.write("3. 在工资核算表中进行汇总计算\n") + f.write("4. 生成最终的工资计算结果\n\n") + + return report_path + +def main(): + """主函数""" + base_path = "/Users/mr.wang/代码库/绿纤/lvqianmeiye_ERP/参考资料/工资核算 -7月" + + # 要分析的文件列表 + files_to_analyze = [ + "工资(全字段).xlsx", + "①B-a-26考勤汇总表.xlsx", + "②B-a-17每日早报.xlsx", + "③B-a-③呈现-消耗明细表.xlsx", + "④B-a-25社保统计表.xlsx", + "⑤B-a-12奖励统计表.xlsx", + "B-b-③健康师底薪.xlsx", + "B-b-④健康师提成-金三角顾问.xlsx", + "B-b-⑤其他岗位工资.xlsx", + "B-b-⑤当月数据及门店毛利.xlsx" + ] + + all_formulas = [] + all_references = [] + + print("开始分析Excel公式...") + print("=" * 60) + + for filename in files_to_analyze: + file_path = os.path.join(base_path, filename) + if os.path.exists(file_path): + print(f"正在分析: {filename}") + formulas, references = extract_formulas_from_excel(file_path) + all_formulas.extend(formulas) + all_references.extend(references) + print(f" 发现 {len(formulas)} 个公式") + else: + print(f"文件不存在: {filename}") + + # 分析依赖关系 + dependencies = analyze_formula_dependencies(all_formulas) + + # 生成报告 + report_path = generate_formula_report(all_formulas, all_references, dependencies) + + print(f"\n公式分析完成!") + print(f"总公式数量: {len(all_formulas)}") + print(f"总引用数量: {len(all_references)}") + print(f"分析报告: {report_path}") + +if __name__ == "__main__": + main() diff --git a/antis-ncc-admin/.DS_Store b/antis-ncc-admin/.DS_Store index 717afe4..8d0515c 100644 --- a/antis-ncc-admin/.DS_Store +++ b/antis-ncc-admin/.DS_Store diff --git a/antis-ncc-admin/.nvmrc b/antis-ncc-admin/.nvmrc new file mode 100644 index 0000000..eda3661 --- /dev/null +++ b/antis-ncc-admin/.nvmrc @@ -0,0 +1,2 @@ +16.20.2 + diff --git a/antis-ncc-admin/package-lock.json b/antis-ncc-admin/package-lock.json index 69ceb73..e2c24d2 100644 --- a/antis-ncc-admin/package-lock.json +++ b/antis-ncc-admin/package-lock.json @@ -13634,6 +13634,14 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "node_modules/nan": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -27809,6 +27817,7 @@ }, "eve": { "version": "git+ssh://git@github.com/adobe-webplatform/eve.git#eef80ed8d188423c2272746fb8ae5cc8dad84cb1", + "integrity": "sha512-VrMCMjRWGSuyiV/1SP58K4lIui3jlfD3uBapV8jahx9/RsqZad/FL7Tq5NRTHWFI8yd1dVLgUrEDPrA70gnOTw==", "from": "eve@git://github.com/adobe-webplatform/eve.git#eef80ed" }, "event-pubsub": { @@ -32943,6 +32952,13 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "nan": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", + "dev": true, + "optional": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -36827,6 +36843,7 @@ }, "squire-rte": { "version": "git+ssh://git@github.com/sohee-lee7/Squire.git#b1e0e1031fa18912d233c204cbe7c7fae4a42621", + "integrity": "sha512-/1Wi323QPO3AmcGOXjliEp2Kqzse6/BbCyCj/lw0R0M/zS+7IFm1LnBlgMlfa1yLXRjNcc5PcmE2vnwA4Zlhkg==", "from": "squire-rte@github:sohee-lee7/Squire#b1e0e1031fa18912d233c204cbe7c7fae4a42621" }, "sshpk": { diff --git a/antis-ncc-admin/package.json b/antis-ncc-admin/package.json index b894511..cc4492a 100644 --- a/antis-ncc-admin/package.json +++ b/antis-ncc-admin/package.json @@ -6,6 +6,7 @@ "license": "MIT", "scripts": { "dev": "vue-cli-service serve --open", + "dev:legacy": "NODE_OPTIONS=\"--openssl-legacy-provider\" vue-cli-service serve --open", "build": "cross-env NODE_ENV=production vue-cli-service build", "build:staging": "cross-env NODE_ENV=production vue-cli-service build --mode staging", "build:javaBootDev": "cross-env NODE_ENV=production vue-cli-service build --mode javaBootDev", diff --git a/antis-ncc-admin/start-dev.sh b/antis-ncc-admin/start-dev.sh new file mode 100755 index 0000000..38309ed --- /dev/null +++ b/antis-ncc-admin/start-dev.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# 绿纤ERP前端启动脚本 +echo "🚀 启动绿纤ERP前端项目..." + +# 检查nvm是否安装 +if ! command -v nvm &> /dev/null; then + echo "❌ nvm未安装,请先安装nvm" + exit 1 +fi + +# 切换到项目目录 +cd "$(dirname "$0")" + +# 使用nvm切换到指定Node.js版本 +echo "📦 切换到Node.js 16.20.2..." +nvm use + +# 检查Node.js版本 +echo "✅ 当前Node.js版本: $(node --version)" + +# 安装依赖(如果需要) +if [ ! -d "node_modules" ]; then + echo "📥 安装项目依赖..." + npm install +fi + +# 启动开发服务器 +echo "🌐 启动前端开发服务器..." +echo "📍 访问地址: http://localhost:3000" +echo "🛑 按 Ctrl+C 停止服务" +echo "" + +npm run dev + diff --git a/netcore/.DS_Store b/netcore/.DS_Store index eed6163..f99cfe6 100644 --- a/netcore/.DS_Store +++ b/netcore/.DS_Store diff --git a/netcore/src/.DS_Store b/netcore/src/.DS_Store index fb4e3ff..746a14d 100644 --- a/netcore/src/.DS_Store +++ b/netcore/src/.DS_Store diff --git a/netcore/src/Application/.DS_Store b/netcore/src/Application/.DS_Store index a45b207..9f1b196 100644 --- a/netcore/src/Application/.DS_Store +++ b/netcore/src/Application/.DS_Store diff --git a/netcore/src/Application/NCC.API.Core/Startup.cs b/netcore/src/Application/NCC.API.Core/Startup.cs index 8cdae9f..d831d65 100644 --- a/netcore/src/Application/NCC.API.Core/Startup.cs +++ b/netcore/src/Application/NCC.API.Core/Startup.cs @@ -30,6 +30,7 @@ using Antis.Pay.Core.Interface; using Antis.Pay.Core; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; +using NCC.Extend.Utils; namespace NCC.API.Core { @@ -58,6 +59,12 @@ namespace NCC.API.Core services.AddConfigurableOptions(); //使用微信支付实现 services.AddScoped(); + + // 注册企业微信机器人服务 + services.AddHttpClient(); + + // 注册开单记录字符串生成器 + services.AddScoped(); services.AddControllersWithViews() .AddMvcFilter() diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs index 68ffc2a..2422ed2 100644 --- a/netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqKdKdjlbService.cs @@ -22,6 +22,8 @@ using NCC.Common.Model.NPOI; using NCC.Common.Configuration; using NCC.DataEncryption; using NCC.ClayObject; +using NCC.Extend.Utils; +using System.Net.Http; namespace NCC.Extend.LqKdKdjlb { @@ -38,6 +40,8 @@ namespace NCC.Extend.LqKdKdjlb private readonly ISqlSugarRepository _lqKdPxmxRepository; private readonly SqlSugarScope _db; private readonly IUserManager _userManager; + private readonly WeChatBotService _weChatBotService; + private readonly LqKdKdjlbStringGenerator _stringGenerator; /// /// 初始化一个类型的新实例 @@ -47,7 +51,9 @@ namespace NCC.Extend.LqKdKdjlb ISqlSugarRepository lqKdJksyjRepository, ISqlSugarRepository lqKdKjbsyjRepository, ISqlSugarRepository lqKdPxmxRepository, - IUserManager userManager) + IUserManager userManager, + WeChatBotService weChatBotService, + LqKdKdjlbStringGenerator stringGenerator) { _lqKdKdjlbRepository = lqKdKdjlbRepository; _db = _lqKdKdjlbRepository.Context; @@ -55,6 +61,8 @@ namespace NCC.Extend.LqKdKdjlb _lqKdKjbsyjRepository = lqKdKjbsyjRepository; _lqKdPxmxRepository = lqKdPxmxRepository; _userManager = userManager; + _weChatBotService = weChatBotService; + _stringGenerator = stringGenerator; } /// @@ -203,6 +211,41 @@ namespace NCC.Extend.LqKdKdjlb //关闭事务 _db.CommitTran(); + + // 生成开单记录字符串并发送到企业微信 + try + { + var entityInfo = await GetInfo(newEntity.Id); + if (entityInfo != null) + { + var orderRecordString = _stringGenerator.GenerateOrderRecordString(entityInfo); + Console.WriteLine("开单记录字符串生成成功:"); + Console.WriteLine(orderRecordString); + + // 发送到企业微信群 + try + { + var sendResult = await _weChatBotService.SendOrderRecordMessage(orderRecordString); + if (sendResult) + { + Console.WriteLine("开单记录已成功发送到企业微信群"); + } + else + { + Console.WriteLine("开单记录发送到企业微信群失败"); + } + } + catch (Exception wechatEx) + { + Console.WriteLine($"发送企业微信消息异常: {wechatEx.Message}"); + } + } + } + catch (Exception ex) + { + // 字符串生成失败不影响主流程,只记录日志 + Console.WriteLine($"生成开单记录字符串失败: {ex.Message}"); + } } catch (Exception) { @@ -473,5 +516,6 @@ namespace NCC.Extend.LqKdKdjlb throw NCCException.Oh(ErrorCode.COM1002); } } + } } diff --git a/netcore/src/Modularity/Extend/NCC.Extend/Utils/LqKdKdjlbStringGenerator.cs b/netcore/src/Modularity/Extend/NCC.Extend/Utils/LqKdKdjlbStringGenerator.cs new file mode 100644 index 0000000..17c6b15 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend/Utils/LqKdKdjlbStringGenerator.cs @@ -0,0 +1,253 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NCC.Extend.Entitys.Dto.LqKdKdjlb; +using NCC.Extend.Entitys; +using NCC.System.Entitys.Permission; +using SqlSugar; + +namespace NCC.Extend.Utils +{ + /// + /// 开单记录字符串生成器 + /// + public class LqKdKdjlbStringGenerator + { + private readonly ISqlSugarClient _db; + + public LqKdKdjlbStringGenerator(ISqlSugarClient db) + { + _db = db; + } + + /// + /// 生成开单记录字符串 + /// + /// 开单记录实体 + /// 格式化的字符串 + public string GenerateOrderRecordString(LqKdKdjlbInfoOutput entity) + { + if (entity == null) + { + return string.Empty; + } + var sb = new StringBuilder(); + // 店名:龙城国际店 - 获取显示名称 + var storeName = GetStoreDisplayName(entity.djmd); + sb.AppendLine($"⏩店名:{storeName}"); + // 金三角:ko队 - 获取部门显示名称 + var departmentName = GetDepartmentDisplayName(entity.jsj); + sb.AppendLine($"⏩金三角:{departmentName}"); + // 顾客姓名:高华 - 通过客户ID查询客户名称 + var customerName = GetCustomerName(entity.kdhy); + sb.AppendLine($"⏩顾客姓名:{customerName}"); + // 健康师:王维 + var healthTeachers = GetHealthTeachers(entity.lqKdJksyjList); + sb.AppendLine($"⏩健康师:{healthTeachers}"); + + // 活动方案:532工程 + sb.AppendLine($"⏩活动方案:{entity.pxxx ?? "无"}"); + + // 跟单配合:王经理 竹主任 陈思思老师 + var techTeachers = GetTechTeachers(entity.lqKdKjbsyjList); + sb.AppendLine($"⏩跟单配合:{techTeachers}"); + + // 业绩:4800 + sb.AppendLine($"⏩业绩:{entity.zdyj}"); + + // 实付:4800 + sb.AppendLine($"⏩实付:{entity.sfyj}"); + + // 欠款: + sb.AppendLine($"⏩欠款: {entity.qk}"); + + // 抵扣: + sb.AppendLine($"⏩抵扣:{entity.ckmx ?? "无"}"); + + // 来源:售后 + sb.AppendLine($"⏩来源:{entity.khly ?? "无"}"); + + // 是否属于升单: + sb.AppendLine($"⏩是否属于升单:{entity.sfskdd ?? "无"}"); + + // 简介:高姐是我们的老客,今天邀约到犀浦店做532,维维全程陪同,陈思思老师在操作过程中给姐姐分享企业文化,找到顾客需求、邀请王经理 竹主任 给到顾客福利、顾客爽快成交,私密档案已了解到70%,感谢顾客的信任与支持 ,王经理 竹主任 陈老师辛苦了[玫瑰]维维真棒[强]龙城国际店加油!我们还在努力中!家人们给我们打气加油👏👏👏👏等待我们的捷报👍👍 + sb.AppendLine($"⏩简介:{entity.jj ?? "无"}"); + + return sb.ToString(); + } + + /// + /// 获取门店显示名称 + /// + /// 门店编码 + /// 门店显示名称 + private string GetStoreDisplayName(string storeCode) + { + if (string.IsNullOrEmpty(storeCode)) + { + return "无"; + } + + try + { + var store = _db.Queryable() + .Where(x => x.Mdbm == storeCode) + .First(); + + return store?.Dm ?? storeCode; + } + catch + { + return storeCode; + } + } + + /// + /// 获取部门显示名称 + /// + /// 部门编码 + /// 部门显示名称 + private string GetDepartmentDisplayName(string departmentCode) + { + if (string.IsNullOrEmpty(departmentCode)) + { + return "无"; + } + + try + { + var department = _db.Queryable() + .Where(x => x.Id == departmentCode) + .First(); + + return department?.Jsj ?? departmentCode; + } + catch + { + return departmentCode; + } + } + + /// + /// 获取健康师信息 + /// + /// 健康师列表 + /// 健康师姓名字符串 + private string GetHealthTeachers(List healthTeacherList) + { + if (healthTeacherList == null || !healthTeacherList.Any()) + { + return "无"; + } + + var names = new List(); + foreach (var teacher in healthTeacherList) + { + if (!string.IsNullOrEmpty(teacher.jks)) + { + // 通过账号查询用户真实姓名 + var realName = GetUserRealNameByAccount(teacher.jks); + if (!string.IsNullOrEmpty(realName)) + { + names.Add(realName); + } + } + else if (!string.IsNullOrEmpty(teacher.jksxm)) + { + // 如果没有账号,使用原有的姓名字段 + names.Add(teacher.jksxm); + } + } + + return names.Distinct().Any() ? string.Join(" ", names.Distinct()) : "无"; + } + + /// + /// 获取科技部老师信息 + /// + /// 科技部老师列表 + /// 科技部老师姓名字符串 + private string GetTechTeachers(List techTeacherList) + { + if (techTeacherList == null || !techTeacherList.Any()) + { + return "无"; + } + + var names = new List(); + foreach (var teacher in techTeacherList) + { + if (!string.IsNullOrEmpty(teacher.kjbls)) + { + // 通过账号查询用户真实姓名 + var realName = GetUserRealNameByAccount(teacher.kjbls); + if (!string.IsNullOrEmpty(realName)) + { + names.Add(realName); + } + } + else if (!string.IsNullOrEmpty(teacher.kjblsxm)) + { + // 如果没有账号,使用原有的姓名字段 + names.Add(teacher.kjblsxm); + } + } + + return names.Distinct().Any() ? string.Join(" ", names.Distinct()) : "无"; + } + + /// + /// 获取客户名称 + /// + /// 客户ID + /// 客户名称 + private string GetCustomerName(string customerId) + { + if (string.IsNullOrEmpty(customerId)) + { + return "无"; + } + + try + { + var customer = _db.Queryable() + .Where(x => x.Id == customerId) + .First(); + + return customer?.Khmc ?? "无"; + } + catch + { + return "无"; + } + } + + /// + /// 通过账号查询用户真实姓名 + /// + /// 用户账号 + /// 用户真实姓名 + private string GetUserRealNameByAccount(string account) + { + if (string.IsNullOrEmpty(account)) + { + return string.Empty; + } + + try + { + var user = _db.Queryable() + .Where(x => x.Account == account && x.DeleteMark == null) + .First(); + + return user?.RealName ?? string.Empty; + } + catch + { + return string.Empty; + } + } + + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotService.cs b/netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotService.cs new file mode 100644 index 0000000..ce4f174 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotService.cs @@ -0,0 +1,84 @@ +using System; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace NCC.Extend.Utils +{ + /// + /// 企业微信机器人服务 + /// + public class WeChatBotService + { + private readonly HttpClient _httpClient; + private const string BOT_API_URL = "http://wx.lvqianmeiye.com/api/Bot/send-text"; + private const string WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=6f8686ec-5011-4c1d-bae9-d82a2a2f4d83"; + + public WeChatBotService(HttpClient httpClient) + { + _httpClient = httpClient; + } + + /// + /// 发送文本消息到企业微信群 + /// + /// 消息内容 + /// 发送结果 + public async Task SendTextMessage(string content) + { + try + { + var requestData = new + { + webhookUrl = WEBHOOK_URL, + content = content, + mentionedList = (string)null, + mentionedMobileList = (string)null + }; + + var json = JsonConvert.SerializeObject(requestData); + var httpContent = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = await _httpClient.PostAsync(BOT_API_URL, httpContent); + + if (response.IsSuccessStatusCode) + { + var responseContent = await response.Content.ReadAsStringAsync(); + Console.WriteLine($"企业微信消息发送成功: {responseContent}"); + return true; + } + else + { + var errorContent = await response.Content.ReadAsStringAsync(); + Console.WriteLine($"企业微信消息发送失败: {response.StatusCode} - {errorContent}"); + return false; + } + } + catch (Exception ex) + { + Console.WriteLine($"企业微信消息发送异常: {ex.Message}"); + return false; + } + } + + /// + /// 发送开单记录消息 + /// + /// 开单记录字符串 + /// 发送结果 + public async Task SendOrderRecordMessage(string orderRecordString) + { + if (string.IsNullOrEmpty(orderRecordString)) + { + Console.WriteLine("开单记录字符串为空,跳过发送"); + return false; + } + + // 添加标题和格式化 + var messageContent = $"🎉 新开单记录\n\n{orderRecordString}"; + + return await SendTextMessage(messageContent); + } + } +} diff --git a/netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotTestController.cs b/netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotTestController.cs new file mode 100644 index 0000000..8afbae1 --- /dev/null +++ b/netcore/src/Modularity/Extend/NCC.Extend/Utils/WeChatBotTestController.cs @@ -0,0 +1,100 @@ +using Microsoft.AspNetCore.Mvc; +using NCC.DynamicApiController; +using NCC.Dependency; +using System.Threading.Tasks; +using System.Collections.Generic; +using NCC.Extend.Entitys.Dto.LqKdKdjlb; + +namespace NCC.Extend.Utils +{ + /// + /// 企业微信机器人测试控制器 + /// + [ApiDescriptionSettings(Tag = "Extend", Name = "WeChatBotTest", Order = 200)] + [Route("api/Extend/[controller]")] + public class WeChatBotTestController : IDynamicApiController, ITransient + { + private readonly WeChatBotService _weChatBotService; + private readonly LqKdKdjlbStringGenerator _stringGenerator; + + public WeChatBotTestController(WeChatBotService weChatBotService, LqKdKdjlbStringGenerator stringGenerator) + { + _weChatBotService = weChatBotService; + _stringGenerator = stringGenerator; + } + + /// + /// 测试发送文本消息 + /// + /// 消息内容 + /// 发送结果 + [HttpPost("SendText")] + public async Task SendTextMessage(string content = "这是一条测试消息") + { + return await _weChatBotService.SendTextMessage(content); + } + + /// + /// 测试发送开单记录消息 + /// + /// 发送结果 + [HttpPost("SendOrderRecord")] + public async Task SendOrderRecordMessage() + { + var testOrderRecord = @"---------------- +⏩店名:测试门店 +⏩金三角:测试团队 +⏩顾客姓名:测试客户 +⏩健康师:测试健康师 +⏩活动方案:测试方案 +⏩跟单配合:测试配合 +⏩业绩:1000 +⏩实付:1000 +⏩欠款: 0 +⏩抵扣:无 +⏩来源:测试来源 +⏩是否属于升单:无 +⏩简介:这是一条测试开单记录"; + + return await _weChatBotService.SendOrderRecordMessage(testOrderRecord); + } + + /// + /// 测试字符串生成器(验证显示名称功能) + /// + /// 生成的字符串 + [HttpPost("TestStringGenerator")] + public string TestStringGenerator() + { + // 创建测试数据 + var testEntity = new LqKdKdjlbInfoOutput + { + id = "test001", + djmd = "TEST001", // 门店编码 + jsj = "DEPT001", // 部门编码 + kdhy = "CUSTOMER001", // 客户ID + kdhyc = "测试客户", + pxxx = "测试方案", + zdyj = 1000, + sfyj = 1000, + qk = 0, + ckmx = "无", + khly = "测试来源", + sfskdd = "无", + jj = "这是一条测试开单记录", + lqKdJksyjList = new List + { + new LqKdJksyjInfoOutput { jks = "test_health_1", jksxm = "测试健康师1" }, + new LqKdJksyjInfoOutput { jks = "test_health_2", jksxm = "测试健康师2" } + }, + lqKdKjbsyjList = new List + { + new LqKdKjbsyjInfoOutput { kjbls = "test_tech_1", kjblsxm = "测试科技部1" }, + new LqKdKjbsyjInfoOutput { kjbls = "test_tech_2", kjblsxm = "测试科技部2" } + } + }; + + return _stringGenerator.GenerateOrderRecordString(testEntity); + } + } +} diff --git a/参考资料/.DS_Store b/参考资料/.DS_Store new file mode 100644 index 0000000..253eac6 --- /dev/null +++ b/参考资料/.DS_Store diff --git a/参考资料/工资核算 -7月/.DS_Store b/参考资料/工资核算 -7月/.DS_Store new file mode 100644 index 0000000..116a05c --- /dev/null +++ b/参考资料/工资核算 -7月/.DS_Store diff --git a/参考资料/工资核算 -7月/B-b-③健康师底薪.xlsx b/参考资料/工资核算 -7月/B-b-③健康师底薪.xlsx new file mode 100644 index 0000000..1872e23 --- /dev/null +++ b/参考资料/工资核算 -7月/B-b-③健康师底薪.xlsx diff --git a/参考资料/工资核算 -7月/B-b-④健康师提成-金三角顾问.xlsx b/参考资料/工资核算 -7月/B-b-④健康师提成-金三角顾问.xlsx new file mode 100644 index 0000000..02ea4cb --- /dev/null +++ b/参考资料/工资核算 -7月/B-b-④健康师提成-金三角顾问.xlsx diff --git a/参考资料/工资核算 -7月/B-b-⑤其他岗位工资.xlsx b/参考资料/工资核算 -7月/B-b-⑤其他岗位工资.xlsx new file mode 100644 index 0000000..4a76ec6 --- /dev/null +++ b/参考资料/工资核算 -7月/B-b-⑤其他岗位工资.xlsx diff --git a/参考资料/工资核算 -7月/B-b-⑤当月数据及门店毛利.xlsx b/参考资料/工资核算 -7月/B-b-⑤当月数据及门店毛利.xlsx new file mode 100644 index 0000000..42fa613 --- /dev/null +++ b/参考资料/工资核算 -7月/B-b-⑤当月数据及门店毛利.xlsx diff --git a/参考资料/工资核算 -7月/①B-a-26考勤汇总表.xlsx b/参考资料/工资核算 -7月/①B-a-26考勤汇总表.xlsx new file mode 100644 index 0000000..6f0e967 --- /dev/null +++ b/参考资料/工资核算 -7月/①B-a-26考勤汇总表.xlsx diff --git a/参考资料/工资核算 -7月/②B-a-17每日早报.xlsx b/参考资料/工资核算 -7月/②B-a-17每日早报.xlsx new file mode 100644 index 0000000..e69167f --- /dev/null +++ b/参考资料/工资核算 -7月/②B-a-17每日早报.xlsx diff --git a/参考资料/工资核算 -7月/③B-a-③呈现-消耗明细表.xlsx b/参考资料/工资核算 -7月/③B-a-③呈现-消耗明细表.xlsx new file mode 100644 index 0000000..42b1503 --- /dev/null +++ b/参考资料/工资核算 -7月/③B-a-③呈现-消耗明细表.xlsx diff --git a/参考资料/工资核算 -7月/④B-a-25社保统计表.xlsx b/参考资料/工资核算 -7月/④B-a-25社保统计表.xlsx new file mode 100644 index 0000000..8e45b2a --- /dev/null +++ b/参考资料/工资核算 -7月/④B-a-25社保统计表.xlsx diff --git a/参考资料/工资核算 -7月/⑤B-a-12奖励统计表.xlsx b/参考资料/工资核算 -7月/⑤B-a-12奖励统计表.xlsx new file mode 100644 index 0000000..245dff7 --- /dev/null +++ b/参考资料/工资核算 -7月/⑤B-a-12奖励统计表.xlsx diff --git a/参考资料/工资核算 -7月/外部表单/2025年7月工资(2)(3)(2) 的副本-郭主管8-14.xlsx b/参考资料/工资核算 -7月/外部表单/2025年7月工资(2)(3)(2) 的副本-郭主管8-14.xlsx new file mode 100644 index 0000000..fbbe6e3 --- /dev/null +++ b/参考资料/工资核算 -7月/外部表单/2025年7月工资(2)(3)(2) 的副本-郭主管8-14.xlsx diff --git a/参考资料/工资核算 -7月/外部表单/2025年7月工资表 的副本-张总裁.xlsx b/参考资料/工资核算 -7月/外部表单/2025年7月工资表 的副本-张总裁.xlsx new file mode 100644 index 0000000..c96bc02 --- /dev/null +++ b/参考资料/工资核算 -7月/外部表单/2025年7月工资表 的副本-张总裁.xlsx diff --git a/参考资料/工资核算 -7月/外部表单/7月-考勤.xlsx b/参考资料/工资核算 -7月/外部表单/7月-考勤.xlsx new file mode 100644 index 0000000..dc9f646 --- /dev/null +++ b/参考资料/工资核算 -7月/外部表单/7月-考勤.xlsx diff --git a/参考资料/工资核算 -7月/工资(全字段).xlsx b/参考资料/工资核算 -7月/工资(全字段).xlsx new file mode 100644 index 0000000..8b23663 --- /dev/null +++ b/参考资料/工资核算 -7月/工资(全字段).xlsx diff --git a/参考资料/工资核算 -7月/流程-工资核算的相关表格及sop流程.xlsx b/参考资料/工资核算 -7月/流程-工资核算的相关表格及sop流程.xlsx new file mode 100644 index 0000000..33e6d8a --- /dev/null +++ b/参考资料/工资核算 -7月/流程-工资核算的相关表格及sop流程.xlsx diff --git a/参考资料/整体-8.15/.DS_Store b/参考资料/整体-8.15/.DS_Store new file mode 100644 index 0000000..65c6b01 --- /dev/null +++ b/参考资料/整体-8.15/.DS_Store diff --git a/参考资料/整体-8.15/2025嘉宾挑战V4.xlsx b/参考资料/整体-8.15/2025嘉宾挑战V4.xlsx new file mode 100644 index 0000000..de7be72 --- /dev/null +++ b/参考资料/整体-8.15/2025嘉宾挑战V4.xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-①前置信息-门店资料(确定版)-8.5更新.xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-①前置信息-门店资料(确定版)-8.5更新.xlsx new file mode 100644 index 0000000..5b54fc9 --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-①前置信息-门店资料(确定版)-8.5更新.xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-②前置信息-人员资料-8.10更新.xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-②前置信息-人员资料-8.10更新.xlsx new file mode 100644 index 0000000..753fe5c --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-②前置信息-人员资料-8.10更新.xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-③前置信息-项目资料(7-24更新).xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-③前置信息-项目资料(7-24更新).xlsx new file mode 100644 index 0000000..3a8dc20 --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-③前置信息-项目资料(7-24更新).xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-④前置信息-客户资料-8.5更新.xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-④前置信息-客户资料-8.5更新.xlsx new file mode 100644 index 0000000..3f8e8a8 --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-④前置信息-客户资料-8.5更新.xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-⑤前置信息-历史数据2024.xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-⑤前置信息-历史数据2024.xlsx new file mode 100644 index 0000000..5420623 --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-⑤前置信息-历史数据2024.xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-⑥前置信息-信息字典-8.5更新.xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-⑥前置信息-信息字典-8.5更新.xlsx new file mode 100644 index 0000000..31359d0 --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-⑥前置信息-信息字典-8.5更新.xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-⑦前置信息-营销活动方案.xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-⑦前置信息-营销活动方案.xlsx new file mode 100644 index 0000000..cafedfc --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-⑦前置信息-营销活动方案.xlsx diff --git a/参考资料/整体-8.15/A-a前置信息/A-a-⑧前置信息-产品资料-8.5更新.xlsx b/参考资料/整体-8.15/A-a前置信息/A-a-⑧前置信息-产品资料-8.5更新.xlsx new file mode 100644 index 0000000..22bafbc --- /dev/null +++ b/参考资料/整体-8.15/A-a前置信息/A-a-⑧前置信息-产品资料-8.5更新.xlsx diff --git a/参考资料/整体-8.15/A-b每月月初设定/①门店目标设定.xlsx b/参考资料/整体-8.15/A-b每月月初设定/①门店目标设定.xlsx new file mode 100644 index 0000000..79b2153 --- /dev/null +++ b/参考资料/整体-8.15/A-b每月月初设定/①门店目标设定.xlsx diff --git a/参考资料/整体-8.15/A-b每月月初设定/②金三角设定.xlsx b/参考资料/整体-8.15/A-b每月月初设定/②金三角设定.xlsx new file mode 100644 index 0000000..0c5c36b --- /dev/null +++ b/参考资料/整体-8.15/A-b每月月初设定/②金三角设定.xlsx diff --git a/参考资料/整体-8.15/A-b每月月初设定/④社保增减-8.5新增.xlsx b/参考资料/整体-8.15/A-b每月月初设定/④社保增减-8.5新增.xlsx new file mode 100644 index 0000000..cc673c1 --- /dev/null +++ b/参考资料/整体-8.15/A-b每月月初设定/④社保增减-8.5新增.xlsx diff --git a/参考资料/整体-8.15/A-b每月月初设定/⑤门店类别及核算信息.xlsx b/参考资料/整体-8.15/A-b每月月初设定/⑤门店类别及核算信息.xlsx new file mode 100644 index 0000000..2cce348 --- /dev/null +++ b/参考资料/整体-8.15/A-b每月月初设定/⑤门店类别及核算信息.xlsx diff --git a/参考资料/整体-8.15/A-b每月月初设定/⑥工资核算浮动条件设置.xlsx b/参考资料/整体-8.15/A-b每月月初设定/⑥工资核算浮动条件设置.xlsx new file mode 100644 index 0000000..53cab11 --- /dev/null +++ b/参考资料/整体-8.15/A-b每月月初设定/⑥工资核算浮动条件设置.xlsx diff --git a/参考资料/整体-8.15/A-b每月月初设定/⑦总经理经理核算条件.xlsx b/参考资料/整体-8.15/A-b每月月初设定/⑦总经理经理核算条件.xlsx new file mode 100644 index 0000000..068f795 --- /dev/null +++ b/参考资料/整体-8.15/A-b每月月初设定/⑦总经理经理核算条件.xlsx diff --git a/参考资料/整体-8.15/A-b每月月初设定/⑧毛巾品类及单价设定.xlsx b/参考资料/整体-8.15/A-b每月月初设定/⑧毛巾品类及单价设定.xlsx new file mode 100644 index 0000000..c17a1da --- /dev/null +++ b/参考资料/整体-8.15/A-b每月月初设定/⑧毛巾品类及单价设定.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/.DS_Store b/参考资料/整体-8.15/A-c日常操作/.DS_Store new file mode 100644 index 0000000..0a1bfea --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/.DS_Store diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-10社保变动-8.5新增.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-10社保变动-8.5新增.xlsx new file mode 100644 index 0000000..f9b05a9 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-10社保变动-8.5新增.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-①请假.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-①请假.xlsx new file mode 100644 index 0000000..d9d2abd --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-①请假.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-②人员调动.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-②人员调动.xlsx new file mode 100644 index 0000000..bcd51b9 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-②人员调动.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-③宿舍.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-③宿舍.xlsx new file mode 100644 index 0000000..f97a5ad --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-③宿舍.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/.DS_Store b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/.DS_Store new file mode 100644 index 0000000..7761a0c --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/.DS_Store diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/副本播报-字段(1).xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/副本播报-字段(1).xlsx new file mode 100644 index 0000000..3c49c2b --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/副本播报-字段(1).xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/拓客字段-报表-奖励-科目/拓客汇总表【带奖励】.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/拓客字段-报表-奖励-科目/拓客汇总表【带奖励】.xlsx new file mode 100644 index 0000000..e12d0b2 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/拓客字段-报表-奖励-科目/拓客汇总表【带奖励】.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/拓客字段-报表-奖励-科目/插件②-拓客.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/拓客字段-报表-奖励-科目/插件②-拓客.xlsx new file mode 100644 index 0000000..d53f321 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/拓客字段-报表-奖励-科目/插件②-拓客.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/插件-预约.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/插件-预约.xlsx new file mode 100644 index 0000000..4c1e9f6 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/插件-预约.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/消耗.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/消耗.xlsx new file mode 100644 index 0000000..28dfeb2 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/消耗.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/退卡.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/退卡.xlsx new file mode 100644 index 0000000..400d913 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/退卡.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/邀约字段-报表/插件③-邀约.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/邀约字段-报表/插件③-邀约.xlsx new file mode 100644 index 0000000..951186b --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑤业务操作-6个版块/邀约字段-报表/插件③-邀约.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑥报销及明细上传.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑥报销及明细上传.xlsx new file mode 100644 index 0000000..7ca161f --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑥报销及明细上传.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑧毛巾的收发登记.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑧毛巾的收发登记.xlsx new file mode 100644 index 0000000..e4dc88c --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑧毛巾的收发登记.xlsx diff --git a/参考资料/整体-8.15/A-c日常操作/A-c-⑨每日工作-科技部.xlsx b/参考资料/整体-8.15/A-c日常操作/A-c-⑨每日工作-科技部.xlsx new file mode 100644 index 0000000..c74dcf6 --- /dev/null +++ b/参考资料/整体-8.15/A-c日常操作/A-c-⑨每日工作-科技部.xlsx diff --git a/参考资料/整体-8.15/B-a-报表字段/B-a-⑧每日早报.xlsx b/参考资料/整体-8.15/B-a-报表字段/B-a-⑧每日早报.xlsx new file mode 100644 index 0000000..abecb5f --- /dev/null +++ b/参考资料/整体-8.15/B-a-报表字段/B-a-⑧每日早报.xlsx diff --git a/参考资料/整体-8.15/B-a-报表字段/B-a-(①-16)报表字段及股份字段.xlsx b/参考资料/整体-8.15/B-a-报表字段/B-a-(①-16)报表字段及股份字段.xlsx new file mode 100644 index 0000000..86bb97b --- /dev/null +++ b/参考资料/整体-8.15/B-a-报表字段/B-a-(①-16)报表字段及股份字段.xlsx diff --git a/参考资料/整体-8.15/B-b-②股份核算套表-8.8.xlsx b/参考资料/整体-8.15/B-b-②股份核算套表-8.8.xlsx new file mode 100644 index 0000000..b013758 --- /dev/null +++ b/参考资料/整体-8.15/B-b-②股份核算套表-8.8.xlsx diff --git a/参考资料/整体-8.15/增加/A-a-①-增加.xlsx b/参考资料/整体-8.15/增加/A-a-①-增加.xlsx new file mode 100644 index 0000000..8e1d822 --- /dev/null +++ b/参考资料/整体-8.15/增加/A-a-①-增加.xlsx diff --git a/参考资料/整体-8.15/增加/A-a-②-增加.xlsx b/参考资料/整体-8.15/增加/A-a-②-增加.xlsx new file mode 100644 index 0000000..2f5d1cd --- /dev/null +++ b/参考资料/整体-8.15/增加/A-a-②-增加.xlsx diff --git a/参考资料/整体-8.15/增加/A-b-②-增加.xlsx b/参考资料/整体-8.15/增加/A-b-②-增加.xlsx new file mode 100644 index 0000000..21daca2 --- /dev/null +++ b/参考资料/整体-8.15/增加/A-b-②-增加.xlsx diff --git a/参考资料/整体-8.15/增加/A-b-⑨-增加.xlsx b/参考资料/整体-8.15/增加/A-b-⑨-增加.xlsx new file mode 100644 index 0000000..4806b9b --- /dev/null +++ b/参考资料/整体-8.15/增加/A-b-⑨-增加.xlsx diff --git a/参考资料/整体-8.15/整体-(8-14更新).xlsx b/参考资料/整体-8.15/整体-(8-14更新).xlsx new file mode 100644 index 0000000..f370f9f --- /dev/null +++ b/参考资料/整体-8.15/整体-(8-14更新).xlsx