新增git操作手册
commit
74f65ae83a
|
|
@ -0,0 +1,8 @@
|
|||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
node_modules/
|
||||
dist/
|
||||
build/
|
||||
.env
|
||||
data
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"python-envs.defaultEnvManager": "ms-python.python:conda",
|
||||
"python-envs.defaultPackageManager": "ms-python.python:conda"
|
||||
}
|
||||
|
|
@ -0,0 +1,279 @@
|
|||
# Git 版本控制入门
|
||||
|
||||
这份文档是给当前项目准备的 Git 使用速查,适合从“手动打压缩包备份”过渡到“用 Git 管理版本”。
|
||||
|
||||
## Git 是什么
|
||||
|
||||
Git 可以理解成一个更聪明的项目快照系统。
|
||||
和手动保存 `xxx_final.zip`、`xxx_最终版.zip` 相比,Git 可以:
|
||||
|
||||
- 记录每次修改
|
||||
- 给每次修改写说明
|
||||
- 查看具体改了哪些文件、哪几行
|
||||
- 随时回退到任意历史版本
|
||||
- 开分支做实验,不影响主线
|
||||
- 配合 GitHub / GitLab 做远程备份
|
||||
|
||||
## 第一次开始使用
|
||||
|
||||
### 1. 确认已经安装 Git
|
||||
|
||||
在终端执行:
|
||||
|
||||
```bash
|
||||
git --version
|
||||
```
|
||||
|
||||
如果能看到版本号,说明已经安装完成。
|
||||
|
||||
### 2. 进入项目目录
|
||||
|
||||
例如当前项目:
|
||||
|
||||
```bash
|
||||
cd d:\github_project\meeting
|
||||
```
|
||||
|
||||
### 3. 初始化 Git 仓库
|
||||
|
||||
```bash
|
||||
git init
|
||||
```
|
||||
|
||||
执行后,项目根目录会出现一个 `.git` 目录,用来保存版本历史。
|
||||
|
||||
### 4. 配置用户名和邮箱
|
||||
|
||||
这一步通常只需要做一次:
|
||||
|
||||
```bash
|
||||
git config --global user.name "你的名字"
|
||||
git config --global user.email "你的邮箱"
|
||||
```
|
||||
|
||||
### 5. 创建 `.gitignore`
|
||||
|
||||
`.gitignore` 用来告诉 Git 哪些文件不需要纳入版本控制,比如缓存、临时文件、依赖目录、构建产物等。
|
||||
|
||||
常见示例:
|
||||
|
||||
```gitignore
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
node_modules/
|
||||
dist/
|
||||
build/
|
||||
.env
|
||||
```
|
||||
|
||||
### 6. 进行第一次提交
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "初始提交"
|
||||
```
|
||||
|
||||
这一步相当于把当前项目拍了一张“可追踪的快照”。
|
||||
|
||||
## 日常最小工作流
|
||||
|
||||
平时开发时,建议按下面顺序操作:
|
||||
|
||||
### 1. 写代码
|
||||
|
||||
完成一个小功能、一个修复,或者一组相关修改。
|
||||
|
||||
### 2. 查看当前状态
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
这个命令会告诉你:
|
||||
|
||||
- 哪些文件被修改了
|
||||
- 哪些文件还没加入暂存区
|
||||
- 哪些文件准备提交
|
||||
|
||||
### 3. 查看具体改了什么
|
||||
|
||||
```bash
|
||||
git diff
|
||||
```
|
||||
|
||||
如果你已经执行过 `git add`,想看暂存区里的内容,可以用:
|
||||
|
||||
```bash
|
||||
git diff --cached
|
||||
```
|
||||
|
||||
### 4. 添加到暂存区
|
||||
|
||||
添加所有改动:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
```
|
||||
|
||||
如果你只想提交某一个文件:
|
||||
|
||||
```bash
|
||||
git add 文件名
|
||||
```
|
||||
|
||||
### 5. 提交一个版本
|
||||
|
||||
```bash
|
||||
git commit -m "修复会议摘要生成错误"
|
||||
```
|
||||
|
||||
建议提交说明写清楚“这次做了什么”,以后回看会非常省心。
|
||||
|
||||
## 最常用命令速查
|
||||
|
||||
```bash
|
||||
git init
|
||||
git status
|
||||
git diff
|
||||
git diff --cached
|
||||
git add .
|
||||
git add 文件名
|
||||
git commit -m "提交说明"
|
||||
git log --oneline
|
||||
git checkout -b 新分支名
|
||||
```
|
||||
|
||||
各命令含义:
|
||||
|
||||
- `git init`:初始化仓库
|
||||
- `git status`:查看当前状态
|
||||
- `git diff`:查看未暂存的改动
|
||||
- `git diff --cached`:查看已暂存但未提交的改动
|
||||
- `git add .`:把当前目录中的改动加入暂存区
|
||||
- `git commit -m "说明"`:提交一个版本
|
||||
- `git log --oneline`:简洁查看提交历史
|
||||
- `git checkout -b 新分支名`:创建并切换到新分支
|
||||
|
||||
## 什么时候提交比较合适
|
||||
|
||||
推荐在下面这些时机提交:
|
||||
|
||||
- 完成一个小功能
|
||||
- 修复一个明确的问题
|
||||
- 做完一次重构
|
||||
- 修改前先做一次提交,方便之后回退
|
||||
|
||||
不建议把很多不相关的改动堆到一次提交里。
|
||||
|
||||
## 提交说明怎么写
|
||||
|
||||
尽量写得具体一点,避免只写“修改”“更新”“调整”。
|
||||
|
||||
好的例子:
|
||||
|
||||
- `初始化会议摘要脚本`
|
||||
- `修复提示词加载路径错误`
|
||||
- `新增前端导出 Markdown 功能`
|
||||
- `优化配置文件读取逻辑`
|
||||
|
||||
不太好的例子:
|
||||
|
||||
- `修改`
|
||||
- `更新`
|
||||
- `test`
|
||||
- `111`
|
||||
|
||||
## 查看历史版本
|
||||
|
||||
查看提交历史:
|
||||
|
||||
```bash
|
||||
git log --oneline
|
||||
```
|
||||
|
||||
你会看到类似:
|
||||
|
||||
```text
|
||||
abc1234 修复会议摘要生成错误
|
||||
def5678 初始提交
|
||||
```
|
||||
|
||||
前面的短串是提交 ID,可以用来定位历史版本。
|
||||
|
||||
## 分支有什么用
|
||||
|
||||
如果你想尝试一个新功能,但又怕把当前稳定版本改坏,可以新建分支:
|
||||
|
||||
```bash
|
||||
git checkout -b new-feature
|
||||
```
|
||||
|
||||
这样你就在一个独立分支里开发,主线不会受影响。
|
||||
等实验成功后,再考虑合并回主分支。
|
||||
|
||||
## Git 和压缩包备份的区别
|
||||
|
||||
你以前的方式:
|
||||
|
||||
- 手动复制项目
|
||||
- 手动压缩
|
||||
- 手动命名
|
||||
- 很难看出两个版本之间具体差了什么
|
||||
|
||||
Git 的方式:
|
||||
|
||||
- 自动记录版本历史
|
||||
- 可以精确查看每次改动
|
||||
- 不需要保存一堆重复压缩包
|
||||
- 回退、对比、分支都更方便
|
||||
|
||||
## 给新手的几个重要提醒
|
||||
|
||||
### 1. Git 不是自动保存
|
||||
|
||||
你必须执行 `git commit`,这次版本才会进入历史记录。
|
||||
|
||||
### 2. 先学最常用的几个命令就够了
|
||||
|
||||
先熟悉这些:
|
||||
|
||||
- `git status`
|
||||
- `git diff`
|
||||
- `git add`
|
||||
- `git commit`
|
||||
- `git log --oneline`
|
||||
|
||||
### 3. 不要把不该提交的东西也提交进去
|
||||
|
||||
例如:
|
||||
|
||||
- 虚拟环境
|
||||
- 缓存文件
|
||||
- 构建产物
|
||||
- 私密配置
|
||||
|
||||
这些应该放进 `.gitignore`。
|
||||
|
||||
## 推荐你现在就用的流程
|
||||
|
||||
如果你的项目已经开始用 Git,之后每次开发可以直接按这个顺序走:
|
||||
|
||||
```bash
|
||||
git status
|
||||
git diff
|
||||
git add .
|
||||
git commit -m "这次修改的内容"
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "优化会议摘要输出格式"
|
||||
```
|
||||
|
||||
## 一句话总结
|
||||
|
||||
压缩包备份适合偶尔存档,Git 更适合持续开发。
|
||||
如果你经常改代码、修问题、加功能,用 Git 会比手动打压缩包轻松很多,也安全很多。
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,24 @@
|
|||
from openai import OpenAI
|
||||
|
||||
client = OpenAI(
|
||||
api_key="unis123",
|
||||
base_url="http://10.100.53.199:9527/v1"
|
||||
)
|
||||
|
||||
def get_qwen_response(model_name, system_prompt, user_prompt, max_token=64000):
|
||||
response = client.chat.completions.create(
|
||||
model=model_name,
|
||||
messages=[
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_prompt}
|
||||
],
|
||||
temperature=0.7,
|
||||
max_tokens=max_token,
|
||||
stream=True
|
||||
)
|
||||
|
||||
for chunk in response:
|
||||
if chunk.choices[0].delta.content is None:
|
||||
yield "reasoning", chunk.choices[0].delta.reasoning
|
||||
else:
|
||||
yield "content", chunk.choices[0].delta.content
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"api_base_url": "https://api.llm.unissense.tech/v1",
|
||||
"api_key": "unis123",
|
||||
"model_name": "Qwen3.6-35B"
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"active_meeting_id": "1778233001316"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "1.7B 大模型",
|
||||
"created_at": "2026-05-08 14:29:07",
|
||||
"original_filename": "1.7B ASR大模型.md"
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
# 文件会议 05-08 10:38 会议转录
|
||||
|
||||
- 会议时间:2026-05-08 10:38:06
|
||||
- 主持人:管理员
|
||||
- 导出时间:2026-05-08 10:50:15
|
||||
|
||||
## 转录正文
|
||||
|
||||
- [00:00:01 - 00:00:05] 未知说话人01: 也是,我们也对宽带的重视,也是有一定的效果。
|
||||
- [00:00:06 - 00:00:37] 未知说话人01: 然后上门处理,因为上周第1个是下雨的原因,第2个导致的安装的上门的量的下降,所以当周的那个上门量还是比较高,580,所以说那个累计上门量达到了1000以上,但是离我们的目标3000户的话,这一块稍微进度还是靠后啊,主要还是因为上门这块和那个和安装这个安装这一块的平衡,要两边都要兼顾,总体的话线路故障的话,这块是比较平稳。
|
||||
- [00:00:37 - 00:00:42] 未知说话人01: 你那个说法,你刚说的本来那个安装没得好多量的噻,不是没得量,下雨。
|
||||
- [00:00:43 - 00:00:58] 未知说话人01: 下雨导致的,上周也下雨。那上门儿都不应该很撇的啊。上门就比较好的,上周上门比较好的。那整个加在一起的话,你前面我们不是累积了35的进度,那个进度不高哦。前面2周不是安装达到了1000嘛,最近。
|
||||
- [00:00:58 - 00:01:02] 未知说话人01: 你给我看后面,我们这上周我们的安装只有接近400。
|
||||
- [00:01:02 - 00:01:17] 未知说话人01: 这个安装量和上门量,它两个还是就是每1周还是达到了将近1000的上门量,就是安装和维护的上门还是有1000,然后每个月的四达到了4000的上门量,然后再看一下那个。
|
||||
- [00:01:17 - 00:02:06] 未知说话人01: 这个刚说的就是那个上门整个指标的情况的话,就是从上门之后的指标几个关键指标,第1个是弱光,弱光现在目前是0.51,也是在上周持续在向好,即将达到0.5的那个目标。三类终端也是因为全年,因为去年的目标是7.5,今年要求的年度目标是5.5,所以说这个需要一个持续往下压的过程,这个也是较上周提升了0.1个百分点,就是下降了,就是有改善。所以说这个是年度目标的话,我也跟司公司建议了,这个指标它会纳入到运维,我也建议他们那个每一个季度是一个阶段性的目标,不然的话全市的话5.5都达不到,现在目前。FTDR现在是达标的,就上周这块没达标,主动跟进这块是靠后的,0.3,这是一个上门之后的效果。
|
||||
- [00:02:07 - 00:02:40] 未知说话人01: 然后那个九零工程转化率要达到90%,退单率要低于7.5。然后整个月度来看的话,我们现在是转化率是87.35,离90的目标还差一点点。但是当周来看的话,主要是天气影响啊,当周虽然上了80%,但是离90的目标还是差很远。但是月度来看的话,都是转化率还是有很大的提升,接近90,退单率是6.53。整个退单的那个改约的情况是影响那个转化率的一个主要因素,主要是用户原因29单,覆盖6单,天气2单。
|
||||
- [00:02:41 - 00:02:47] 未知说话人01: 整个退单来看的话,主要是用户不安装退单16单,长期无法联系3单。
|
||||
- [00:02:48 - 00:03:06] 未知说话人01: 还有入错4单,低价值不可见是用户入网不通哈这块,三块蓝单的话就是上周的话那个没达到80%哈56.82,整体的当月的转化率是75.29,也是离八十还是稍微还差一点点,退单率是44.29。
|
||||
- [00:03:07 - 00:03:51] 未知说话人01: 然后退单率比较高的原因,主要还是那个 BTC 的这一块的那个协调问题,这块一个是审核,车单的退单的流程审核已经给施工司那个建议了,当时那个运营经理也专门给我打电话啊,他也是明白了我们想说的那个这个审核的一个流程意识,他们也在正在开发。然后同时的话,也那个这个指标也会是我们综合运维的一个考核指标,我们也建议了施工司上次来也建议他们这个退单率应该看能不能剔除这种分局长,如果这种一线审批如果同意了,我觉得还是应该剔除掉,不然的话这种黄单来了之后啊,都是他自己有一些个人的意识在里面要退单啊。
|
||||
- [00:03:53 - 00:04:21] 未知说话人01: PCTN那个专线持续在恶化,然后主要还是学校,就是当月3月份的话是开学之后啊是4.84,这个的话一个就是我们把那个涉及到的IP地址已经报市公司帮我们分析这个出口的学校的IP地址,因为目前数据我们上周跟他们沟通之后,他们现在这1周才能反馈那个,啊是集中在一个学校吗?两个学校,人文和是海南还是海师,就两个学校。
|
||||
- [00:04:22 - 00:05:31] 未知说话人01: 但这个报了全资以后,他是马上就会过限速啊?呃,他是要把 IP 地址分析出来之后,要报给学校限速。学校他们现,他们现在也在协同他们。啊?我我们也在找全资,他们能不能帮我们后台线建立这种机制?因为三宽,因为加宽和起宽现在都已经都施工都不通报了,周报也没有了。主要是现在主要问题还是在专线。问问题是专线主要还是在学校我们,学校的话,因为我们只是提供他的出口带宽,他的 IP 地址啊那些所有的话,要经过那个。而且学校的话,互联网带宽我们是没收费的。对。这个是更不应该出现问题了。啊。他们这个学校这边的话,如果有问题,我觉得第1时间就应该直接就在系统上线。对我们也在想这个事。正常的这个行为。我们也想在那个。那全是在沟通一下嘛?就是一旦发现直接限掉,他也没什么好说的。他作为一个学校,或者是那个什么,他提供的是正常的那个带宽使用的这个速度,如果他那个这个超过了这个的话,那这他自己有问题啊。,我现在协调全资
|
||||
- [00:05:33 - 00:05:41] 未知说话人01: 好,这是整个那个PCDN啊,三创空间主要1项没达标,主要就是那个物业点那个本月那个。
|
||||
- [00:05:42 - 00:05:49] 未知说话人01: 那个之前是计划的本月,但是反馈天线哈现在没有货,预计4月初进行一个检测轨道。
|
||||
- [00:05:50 - 00:05:52] 未知说话人01: 其他的都是达标的。
|
||||
- [00:05:53 - 00:06:28] 未知说话人01: 然后畅听也有1项,主要是那个其实问题都解决了,但就是要带智能体要智能判断,声音工单要逐项的核查是否达标才能算解决。所以说虽然是处理了,但是要等到质检,其他指标都是达标的。然后还有1个有2项自行工作啊,只能添加的就是也包括兰总也在反馈,就是我们有些打接电话没有接到,然后他们也是,当周的现在目前的解决方案是爱信5G基站参数的调整试点,待观察效果。这个近期反映的就是有弱化这种情况比较多,5G这一块。
|
||||
- [00:06:32 - 00:07:03] 未知说话人01: 然后那个畅想这块全部达标,这不对是吧?然后那个超频站点的攻坚这块十四公司还是比较那个有帮助,就是上周我们发现了三个超频基站,呃有两个原因是铁塔的开关电源故障导致电流不稳,所以说也及时的处理就进行了一个恢复,然后还有1个就是传输光衰过大,这个维护部人员更换前级后恢复,这个也自动把它解决了。然后旁站的故障的话也持续在也是处理也比较低。
|
||||
- [00:07:03 - 00:07:56] 未知说话人01: 然后专线护航,目前来讲的话,118条专线,我们目前的话有存量的73条的话,已经完成巡检56条,还有17条,然后未验收的工程已经建设的有45条全部进行了巡检,然后四公司要求是3月底全量完成巡检,目前17条的话,我们在月底能够按时进行一个全部巡检的完成。然后主要是那个涉及到存量这一块,我们已经给改的改了,主要还是涉及到光缆路由的这块有抢盘行动,我们会及时的上报给四公司。然后上周的话,我跟机科那边培训,客服室的问题主要还是他们内部的那个,就是他们的机房和机柜这块的问题比较严重,这块也是今天我们会就是这1周,这2天会把全量的清单,我们的问题、客服处理问题全量的发给客服经理,让他们知晓并与客服沟通。
|
||||
- [00:07:57 - 00:08:04] 未知说话人01: 然后当周故障的话是收到爆炸是33件,然后9件跟网络相关,主要问题还是光缆这一块的问题啊。
|
||||
- [00:08:07 - 00:08:13] 未知说话人01: 然后东环呢也持续保持一个良好的一个水平,上周还在全市做了一个那个交流。
|
||||
- [00:08:14 - 00:08:53] 未知说话人01: 好,金属管家这一块重点那个说一下二级,因为上周小总也安排了二级,二级的话,整个我们目前,就最新的数据,我们现在剩下2026年总共还剩下一百二十一站,这二百一百二十一站其实上周也是抓紧处理,已经全部下电了。然后目前累计完成拆除是四十六站,还有75站,七十五站预计的话,我们争取的话是在2周之内完成全部量的拆除,然后进行资管的转出以及电量服务费次月的一个调整,也就相当于在4月15号之前可以全量完成二级的拆除和下电和服务费调整。
|
||||
- [00:08:55 - 00:09:04] 未知说话人01: 好,工程下沉项目都和正常,除了那个他们那个单子也在补当中。
|
||||
- [00:09:06 - 00:09:08] 未知说话人01: 其他的就是也都是正常开展的。
|
||||
- [00:09:09 - 00:09:12] 未知说话人01: 其他就是没有啥子大的问题。
|
||||
- [00:09:12 - 00:09:35] 未知说话人01: 还有就是最后一个就是网络质量综合评估体系,虽然没有发文,但是已经给已经发下来了,那个我们内部先收到了,这一块我们会,呃后面就是下1周的话,我们会针对综合网络运维评估体系进行一个那个进行一个分解和目标的一个制定啊,这边就没有其他的。
|
||||
- [00:09:46 - 00:10:00] 未知说话人02: 25年剩余2项工作,第1个花果山那个没得啥子变化的,第2个委托无人机哈是说的在金板人组织验收以后是话本周哈拜访唐书记进行推动,是项目组的一个。
|
||||
- [00:10:01 - 00:11:03] 未知说话人02: 上周完成了5项工作,包括,浙通要求建委哈对施工资管的框架下整理的工作清单,以及投资计划专项评估汇报,建委吴大副是已经汇报并且完成。然后市场那块终端占比问题,呃是进行了一个全方面我们的一个重点的一个汇报,形成了一个五个方面,制定了具体的措施,解决问题推动业务提升啊,大副是已经进行了专题研讨汇报。,郑州安排的收入地图和哈中心的收入地图,是各中心已经完成并且经啊要求进行了提交啊,做一个存档。,打印机哈那块是跟极客到现场办公室沟通以后,现在已经是设备综合部啊专门为我们嘞招投标哈预留1.1元个打印机。同时啊那块我们也在思考哈如何确保哈了解了他们日常需求的呃打印数量哈呃打印情况以后,我们在周边的哈打印店也进行了一些洽谈。
|
||||
- [00:11:04 - 00:11:27] 未知说话人02: 最终,他们的价格偏差还是很大,有十倍以上。好,最最后我们呃跟建呃跟那个叫啥?曾曾涛是吧?啊,秦涛。啊,秦涛沟通以后,到时候我们去试。他有需求的时候,我们陪到一起去试,确保质量的情况下,我们呃提供一个相当于外派点,进行一个保障,确保那个招投标的打印嗯不影响招投标。
|
||||
- [00:11:28 - 00:11:29] 未知说话人02: 然后那个气象。
|
||||
- [00:11:30 - 00:11:42] 未知说话人03: 那个事情跟那个行业中心和那个哎运输中心都说,都是个人自己要晓得哦。下回不要再给我,再给我以那个理由再来说去打你有问题,那都是个人的问题。
|
||||
- [00:11:43 - 00:11:45] 未知说话人03: 请你们通知到位,好吧?
|
||||
- [00:11:48 - 00:12:39] 未知说话人02: 然后有气象工作人员在推动过程中,第1个是前期交办的玉溪数据中心哈整体包装,那块儿是说政府要拿出方案,补贴方案以后,在汇报。,无人机哈那个需求,结合到落实成为河川本地的一个方案,目前没得啥子变化和之前的反馈。,然后基金工作清单和宣传工作计划,中国电在推动基金工作清单儿是公司嗯有延后,目前没下发,下发以后我们再优化制定。啊,宣传工作那块儿目前说滞后,争取本周完成一个那个嗯推动,因为工作人员兼职的原因啊。然后那个嗯渠道那块儿呢有一个产能评估,那块儿是计划。,开了宣贯会,然后还在梳理方案,最后是结合情况,继续在本周进行一个专题汇报。,专线发展节奏的问题,希望整体思考,整体讲。
|
||||
- [00:12:40 - 00:14:53] 未知说话人02: 那个数据进行了展示,然后呃体现的是整体情况,本周专题汇报,呃然后分局支那个支撑优化也用出来过,是形成了那个清单周报,呃然后那个每周与分局进行沟通形成一个清单的一个呃计划,啊具体的优化方案呃完成以后哈进行一个完结,啊类似在跟进的项目,呃综合党群今天有条有些重点工作,请大家知晓,呃3月20号我们也召开了分公司的哈呃工会主席见面,进行了一些沟通,一个是我们对工会经费进行一个公示,啊因为整个工会经费哈从市公司集团到市公司哈再到分公司都有所压价,啊所以今年我们需要以节电耗用更少的钱,办更好的事儿,啊主席给我们做了一些决议,大家啊积极发言,同时今年我们在本周需要上报市公司的暖心工程,呃其中我们已经确定的啊可以上报哈目前沟通的,呃包括我们根石哈包括我们食堂的改造,食堂改造那块儿的话,呃按照之前嘞方案是29.80000,然后我们将会进行一个升级,呃结合到大家用餐的时间,我们提出的建议是5月份结合
|
||||
- [00:14:54 - 00:15:20] 未知说话人02: 更替和修补,同时,市公司,和分公司,我们做了解以后,也是收集大家意见以后,包括,我们准备,引用那个直升机的方式,来解决我们用水的问题,送水啊那些,机器也坏了,直升机那块儿的话也报了市公司,批准,等到其批复以后啊,我们都可以引用,大概在下半年的时候,我们都可以用直升机哈进行引水,同时也节约成本。
|
||||
- [00:15:21 - 00:17:07] 未知说话人02: 幸福一加一的活动,全年分公司组织了六场啊大型活动啊,包括3月的运动会、4月的足球、5月的羽毛球、6月的篮球、10月的气排球和10月的乒乓球。啊,分公司对应除了参加分公司活动以外,整体还安排的有一些重大节假日的一些活动,包括近期我们啊在思考筹备的六一儿童节啊的一个活动,啊以及我们那个啊班组活动,班组活动那块儿的话也是周征求了大家的意见,可能今年我们也在思考是不是搞一个我们分公司内部的班组之间的啊呃气排球比赛啊,通过那种形式哈来解决那个啊班组各自开展活动哈那种另行开展的那种方式,让它更趋近1些啊,也是在一个思考过程中。,同时重点汇报一下周5哈计划的是第4届体育呃文化节啊,我们河川将以河川佳绩,穿越巅峰一起新呃一起新城,然后东亚赛场哈一个主题口号结合到我们泡煮汤哈啊出名的一个形式,通过我们方阵和演员的演出,将我们啊盛情的河川那种啊快乐啊热情的那种精神面貌哈展示给全市
|
||||
- [00:17:08 - 00:17:16] 未知说话人02: 原来黄翔啊,他们都是因为呃有伤在身,无法参加。啊,他们昨日不行啊?啊,他不得行。
|
||||
- [00:17:17 - 00:17:21] 未知说话人02: 他是哪儿手上了啊?呃,他肌肉拉伤。
|
||||
- [00:17:23 - 00:17:26] 未知说话人02: 是没法参加吗?哎,对他不敢跑,他是。
|
||||
- [00:17:27 - 00:17:30] 未知说话人02: 黄香啥情况啊?呃,也是。
|
||||
- [00:17:31 - 00:17:37] 未知说话人03: 两个主力选手都不得行喽,那个金玲子那个有点具体哦,平时主持挺多。
|
||||
- [00:17:38 - 00:17:40] 未知说话人02: 他什么跟我说的?
|
||||
- [00:17:41 - 00:17:43] 未知说话人03: 问我二九九的话,打不起吗?
|
||||
- [00:17:44 - 00:17:48] 未知说话人03: 看到起啊!我说没看到起黑老哥呀。
|
||||
- [00:17:48 - 00:17:56] 未知说话人02: 他不敢爆发性的发力,或者我。啊,那如果是确实手上了,我觉得那就不能勉强,因为不。
|
||||
- [00:17:58 - 00:18:54] 未知说话人02: 好,然后完了以后的话,都是需要各部门儿积极配合,也特此请示领导。一个都是我们方阵,目前除了我们参赛的队员儿和我们呃和本人哈作为方阵队员儿以外,可能我们之外到二十个人来进行那个活动开展。呃,再加上领导和一个举牌手和一个那个形象大使以外,我们一共需要25人。好,我们确定的呃报名人数以外的话,我们还差九个人,还差九个人的话,看呃结合到那个一线生产工作的繁忙,呃那个过度呃看是不是各部门儿再出两个人哈啊,构成我们8人的方阵。另外A运输中心出一个人,我们总共目前差九个人。啊,确定人员的话需要今天确定,确定以后我们需要给他们购买衣服。啊,购买衣服以后周二到周四进行排练,啊就是下班以后,然后星期五就去参加活动。好,那块儿的话看领导觉得合不合适那种分配。
|
||||
- [00:18:55 - 00:18:57] 未知说话人02: 那个男的整起来。
|
||||
- [00:19:00 - 00:19:04] 未知说话人03: 电脑到每个地方,每个部门,两个人给出来,是有效。
|
||||
- [00:19:05 - 00:19:07] 未知说话人02: 周二到周四要排的呀。
|
||||
- [00:19:07 - 00:19:09] 未知说话人02: 大家积极参加。
|
||||
- [00:19:10 - 00:19:13] 未知说话人03: 因为确实住那两个人都看不出来,跟我说。
|
||||
- [00:19:15 - 00:19:17] 未知说话人02: 性别写不呢?呃,不写。
|
||||
- [00:19:19 - 00:19:21] 未知说话人03: 大家说清楚,有衣服的。
|
||||
- [00:19:23 - 00:19:34] 未知说话人02: 同时呢,参加以后,后我还上决策,和往年一样,积极参加的还是有一定的绩效的,一个加分儿。就参加方阵的是每人一分儿,获获得名次的更多一些。
|
||||
- [00:19:36 - 00:19:50] 未知说话人02: 好,第2个都是,请知晓今年主题教育,市公司也是啊,已经发布了第1期的教育简报。好,总体来说都是第1期就是公布公司,好在召开了主题教育的总专题的一个那个啊工作。
|
||||
- [00:19:51 - 00:20:05] 未知说话人02: 好,第2个基层党组织,就上次我们也开了,截止到3月15号,所有的基层党组织也开展了学习,后面我们再按照起那个动作来执行,好,因为呃主题教育进行了知晓动作。第2个就是,市公司也要求哈进行。
|
||||
- [00:20:06 - 00:20:34] 未知说话人02: 招待费哈要进行一个信息公开,好,那块儿公开的对象和范围啊,都是本单位嗯管理层的那个嗯班子成员,那个范围。所以前期我们也是通过邮件的方式,将25年啊招待费的形式进行一个发布和公示也完成了,向纪检组织的啊报备,好,请领导知晓啊,这项工作已经完成。哎,我问一下,他那个公开是每年公开1次吗?还是每1次都要公开呀?每年1次。现在每年。
|
||||
- [00:20:38 - 00:21:59] 未知说话人02: 好,然后那个25年整体招待费使用的情况,那个呃也呃做好做个汇报。25年,我们整体招待费的使用是超我们年初预算是14%,其中综合部哈是逐年增长,24年、25年哈逐年增长,呃增长起来非常明显,超预算也非常多,我们综合部去年超了107%。好,所以26年的话,一个综合部调整了啊预算,其他部门因为涉及到成本的管控,目前没有调整预算。呃,26年使用来看的话,目前也是综合部,呃以及我们嘞市场部,市场部因为年初的渠道大会,啊整体它的那个时间节奏可能不太一样,包括我们超改分局和南京啊分局,相对使用较快,超过时间进度。好,其他一些部门的招待费预算额度还是在这个范围之内,好,可能更多的呃要进行呃特别提醒嘛,我觉得提醒啊、争取啊可以,呃其实是有钱,在那个范围之内可以合理的规划时间进度啊,安排更多的同志,参与的同志都可以报啊,包括呃因为之前我们也盘点了
|
||||
- [00:22:00 - 00:22:09] 未知说话人03: 情况的一个汇报和通报。呃,潘老那边说一下,就是关于正气部啊,因为我们的整个对外招待集中在正气部啊。
|
||||
- [00:22:10 - 00:22:15] 未知说话人03: 正起步那边的话呢,因为有些重要单位又集中在个别的客户经理那点儿。
|
||||
- [00:22:16 - 00:22:19] 未知说话人03: 所以说这种哎,要经营比较统筹。
|
||||
- [00:22:20 - 00:22:23] 未知说话人03: 要统筹安排,你不能说一个客户经理。
|
||||
- [00:22:23 - 00:22:41] 未知说话人03: 太多,是吧?然后比如说有像那种的,比如哎,木青的那边的街坊啊,那些也可以,就大家分到来,好,那边你跟和谐商量,把那个就说实在去是真实发生的费用啊,尽快的解决和。
|
||||
- [00:22:43 - 00:22:46] 未知说话人03: 要拖,我据我老姐去年子,还有1些费用都没还没弄完。
|
||||
- [00:22:47 - 00:22:49] 未知说话人03: 今年子又来了,是吧?
|
||||
- [00:22:49 - 00:22:56] 未知说话人03: 那个事情呢,我认为它是个,不是个啥子大事情,不需要,我们那个公司领导是没来操心的那个事儿。
|
||||
- [00:23:01 - 00:24:22] 未知说话人02: 然后河川区发了一个通知,叫做河川区担当作为先进集体和先进个人,因为之前我们也报过河川强区啊企业类先进集体、先进个人,啊目前还在区领导那,已经嗯提交区领导1个月,目前区领导还在支持。好,同时收到另一个通知,那个文件的话,相当于之前他的那个我们求的文件内容是区级的部门儿啊单位以及区国资委啊管辖的企业,啊因为今年领导班子也特别提到计划,我们要组建在河川区啊加强加呃叫做什么,嗯增强我们区域的影响力,所以我觉得那个可能也是一个点。所以我们也单独进行了一些追踪和呃询问,那个下发单位哈就是区委办啊、府办、嗯区委组织部以及区人力社保局啊,他们组建成立一个专班,啊联系人是委办一个同志和那个社保局的,碰到他们是经办那个负责发文的同志,啊相当于呃经过咨询一个争取到,相当于我们如果有意愿参加的话也可以参加。看了哈前一届的那个评选名单呢,嗯没得那种我们那种企业,都是政府的一些组织和机构,好那块儿呢都是提醒
|
||||
- [00:24:23 - 00:24:40] 未知说话人02: 首先,因为他那个报名简单啊,就是报材料嘛,我们来牵头写,就说看给不给合川移动那个资格啊。有那个资格的话,相当于可以差异化的与竞争对手拉开差距。目前竞争对手应该是对那个还是没有引起重视,也没有动。好,新人集体有三十个,你。
|
||||
- [00:24:42 - 00:24:52] 未知说话人02: 有了名额嘛去报嘛,这是它的程序,要求的是3月31号之前,也是一个网上链接需要进行一个报名,所以用那个事情呢,下面都。
|
||||
- [00:24:53 - 00:24:53] 未知说话人02: 的回报。
|
||||
- [00:24:55 - 00:24:57] 未知说话人02: 好,以上是综合部的汇报。
|
||||
- [00:25:00 - 00:25:02] 未知说话人03: 他达到啥子水平才能够担当?
|
||||
- [00:25:03 - 00:25:07] 未知说话人02: 他跟我们平一样的,都是。
|
||||
- [00:25:08 - 00:25:13] 未知说话人02: 那二十个,类似于二十个方生,都是文字性的。
|
||||
- [00:25:15 - 00:25:16] 未知说话人02: 就是。
|
||||
- [00:25:17 - 00:25:25] 未知说话人02: 就说工作突成绩突出,认真负责,类似于那种的,它都是套话。所以说,那种东西呢,它主要还是在于。
|
||||
- [00:25:27 - 00:25:28] 未知说话人02: 给不给你这个名额?
|
||||
- [00:25:30 - 00:25:38] 未知说话人02: 负责的是委办还是社保局?他们是联合工作组,通知里头有委办和社保局两个联系单位,应该是他们两个都在。
|
||||
- [00:25:39 - 00:26:06] 未知说话人02: 相当于突出的评选都是政治忠诚可靠啊,担当过硬啊,不是套话。哎,所以那工作成绩突出啊,什么呃,整体形象好啊,然后那个纪律严明,就像区那个一样,实际上他也是那种历史套话。啊,所以说那块儿的话,我个人觉得还是从今历史判断来看,还是要有推荐度,然后你再去报,不然的话确实有点浪费。
|
||||
- [00:26:06 - 00:26:15] 未知说话人02: 好,那块儿是委办是叫陈红同志啊,然后人力社保局是叫崔磊同志,也跟他们联系了,他们说他们都是发会议的,具体经办呢。
|
||||
- [00:26:16 - 00:26:20] 未知说话人02: 身后跟那个道士。
|
||||
- [00:26:21 - 00:26:33] 未知说话人02: 没得,没闻到。你要去了解噻。哎,都是可能看那块是正气了解。比如那个石油工业区,可能都是沪江他那边主要那个方面,是吧?然后他那个是哪一个?
|
||||
- [00:26:33 - 00:26:36] 未知说话人03: 就尾巴是那个。
|
||||
- [00:26:37 - 00:26:47] 未知说话人02: 对的,我都是说建议整体跟那么联系,因为我们问了他们的,他说我是发会议的,我不清楚,然后鼓捣他去问的,这个也不太高兴。了解一下嘛,因为那个我没。
|
||||
- [00:26:47 - 00:26:52] 未知说话人03: 那个我们没得好大的那个的话,我们去花那个时间也没得好大意义的。
|
||||
- [00:26:55 - 00:26:58] 未知说话人02: 我印象中,好像那儿发通报的时候。
|
||||
- [00:26:58 - 00:27:05] 未知说话人03: 我说你们去了解一下,如果是那种的话,我们也可以跟那边的领导先沟通一下。
|
||||
- [00:27:06 - 00:27:09] 未知说话人03: 但是我现在不晓得是哪个领导在负责那个事儿。
|
||||
- [00:27:09 - 00:27:25] 未知说话人03: 有你至少是委派主任那个层面吗?或者是,或是分管哪个领导吗?去打听去了解,好吧?好,如果有那的话,我们去争取。如果确实那个都是凭的虚头的,我们也不用花那个时间。
|
||||
- [00:27:25 - 00:27:28] 未知说话人03: 好吧,了解,好吧。
|
||||
- [00:27:29 - 00:27:30] 未知说话人03: 今儿个是聊天。
|
||||
- [00:27:32 - 00:30:23] 未知说话人01: 那个领导,我们整个三个成员的第2期工作做一个嗯简报,首先在查企方面,我们整个刚现在聊村的材料里面,先拿我们整个查企,六千九万成了,1110户,好整个排名呢?统计是哪?我们是,呃查企的方式是我们那个通过党通过那个,就是说在单位上,那么做好那个,做510000的价值提升,就是说他原来的通富没有达到50,我们来提升到50,好那么那个会议,它有里面有好多个成员在说好多事工作,好那么还有1个都是,就是说我们办的那个,比如像新年不查企,都是2次通学,15.1元个月,我们做了两个2次通学,都是一个那个正级成员的一个查企,好那么党叫网查企,都是我们那个新增的通富,好包括有融合套餐,好做了那个还可以1比1的进行刷,好都是一季度的整个查企,是最主要的还是在通富成绩,我们原来通富没达到50的,做一些简单的价值提升,说完成率啊,相对比较好,那个是整个查企的一个
|
||||
- [00:30:23 - 00:31:03] 未知说话人01: 单位上集中做的啊,是和前方的那个,还有京东他们说也有一些社区做的啊,或者说家庭的清洗,和我们那个相结合嘛,两种方式做点看,看哪种效果好。因为像在社区做的啊,我们就像比较像区委组织部家属院、检察院家属院、法院小区,好那种它单位客户比较集中的小区啊,我们去开展一些单位上的客户一些服务工作。啊,那么在那是做的啊,本周的一个做的情况,本周做的啊,一共开展了五场,啊那个龙狮相对较好,那个业务量的话也还是没有达到我们想要的成果,特别是在龙狮上面的签约也好,其他的方面的啊,集资签约的板块的话,那边我在本周啊还要进行一个加强。
|
||||
- [00:31:04 - 00:31:40] 未知说话人01: 商客市场一个情况,整个商客的话,到我们到了1月份,收入是88.5,好比上个一期增加了10000,好完成较好的是草街,那个城北和南京街,增幅都是上20000,好一家农家乐出现了负两百块钱的一个情况,整体个商客的一个规模情况和那个都还是比较好,那个在价值拓展方面的话,我们是完成了115,同比是第6,好下一期我再把其他分公司做一个展示,因为那个我们我积分权限的问题,目前只能看到个人的,好排名是张世龙是稳的,好我下一期把那个整个全市的一个排名啊做一个展现。
|
||||
- [00:31:40 - 00:31:43] 未知说话人01: 那个整个价值拓展的一个情况。
|
||||
- [00:31:44 - 00:32:04] 未知说话人01: 那个重点的工作都在三个经理方面的话,整个,目前我们还有2个人。那边又变成较差的了。,那是以周为单位,周为单位,综合楼的话,那个星期他的那个基础业务只有两笔,所以说相对比较差一点。我们是以周为单位在统计,我下期把累计的,按累计来嘛。
|
||||
- [00:32:05 - 00:32:08] 未知说话人01: 他那个是整个材料费吧?
|
||||
- [00:32:13 - 00:32:14] 未知说话人04: 只需要。
|
||||
- [00:32:15 - 00:32:16] 未知说话人04: 我公司股份还有没得?
|
||||
- [00:32:20 - 00:32:21] 未知说话人05: 在公司。
|
||||
- [00:32:22 - 00:32:25] 未知说话人05: 第1次建委那边,那个鸡翅铺。
|
||||
- [00:32:25 - 00:32:26] 未知说话人05: 之前一个。
|
||||
- [00:32:27 - 00:32:28] 未知说话人05: 就相当于。
|
||||
- [00:32:33 - 00:32:34] 未知说话人06: 咸鱼分区。
|
||||
- [00:32:36 - 00:32:38] 未知说话人06: 每个单位专线,单位啊是。
|
||||
- [00:32:39 - 00:32:40] 未知说话人06: 互相膜拜一下。
|
||||
- [00:32:42 - 00:32:45] 未知说话人05: 第2块,然后再次结合治疗嘞。
|
||||
- [00:32:47 - 00:32:50] 未知说话人05: 结合实际情况,然后而且理了一些,我觉得能够把那个。
|
||||
- [00:32:51 - 00:32:52] 未知说话人05: 公司那个年招的。
|
||||
- [00:32:55 - 00:32:57] 未知说话人05: 进一步结合机房的改造。
|
||||
- [00:33:00 - 00:33:01] 未知说话人07: 厨房的一些。
|
||||
- [00:33:06 - 00:33:09] 未知说话人05: 第2就是,建委今年那个综合评估体系已经出来了。
|
||||
- [00:33:11 - 00:33:12] 未知说话人05: 知道怎么。
|
||||
- [00:33:12 - 00:33:13] 未知说话人05: 把前面的。
|
||||
- [00:33:15 - 00:33:15] 未知说话人05: 要求。
|
||||
- [00:33:19 - 00:33:23] 未知说话人05: 第2个关于吉卡尔号绕轨运输,已经7号都说了,第1个点。
|
||||
- [00:33:24 - 00:33:25] 未知说话人05: 上海的工作。
|
||||
- [00:33:26 - 00:33:29] 未知说话人05: 经理要当天处理,及时回复。
|
||||
- [00:33:30 - 00:33:31] 未知说话人05: 刚刚在商务部通报的。
|
||||
- [00:33:32 - 00:33:36] 未知说话人05: 那个建委部卷,等你收到,人家给我回复,把事情做完结了。
|
||||
- [00:33:37 - 00:33:40] 未知说话人05: 那我们正气他的精力基本上也不在那个那上。
|
||||
- [00:33:41 - 00:33:44] 未知说话人05: 也不好意思哦,我在会上也说了,私下也说了很多次了。
|
||||
- [00:33:45 - 00:33:50] 未知说话人05: 要养成那种日事日清、日清日结、日结日高的好习惯。
|
||||
- [00:33:51 - 00:33:56] 未知说话人05: 就算没完成,阶段性的来沟通1哈儿,有什么问题困难,我们一起来想办法推进。
|
||||
- [00:33:57 - 00:34:01] 未知说话人05: 你不能一个事情,有些工作一说几个月都还差的。
|
||||
- [00:34:04 - 00:34:07] 未知说话人05: 回复工作是首先回复安排工作的领导。
|
||||
- [00:34:09 - 00:34:11] 未知说话人05: 而不是写周报的时候维护综合部。
|
||||
- [00:34:12 - 00:34:15] 未知说话人05: 我要养成好习惯,工作才推得走。
|
||||
- [00:34:15 - 00:34:17] 未知说话人05: 不好意思哦,我做会长得罪了同志们。
|
||||
- [00:34:18 - 00:34:20] 未知说话人05: 我都当好我的嘛。
|
||||
- [00:34:21 - 00:34:23] 未知说话人05: 并且恢复工作一定是要量化的。
|
||||
- [00:34:24 - 00:34:26] 未知说话人05: 要有结果。
|
||||
- [00:34:26 - 00:34:29] 未知说话人05: 要有措施,要有成效。
|
||||
- [00:34:33 - 00:34:46] 未知说话人05: 第2,关于上课这个指标,我也说了很多次了,我也没看到具体的保障措施,只有最后1周了,早上班的时候也跟廖经理做了沟通,希望拿出具体可行的方案。
|
||||
- [00:34:47 - 00:34:50] 未知说话人05: 那个1月5号那天,我都说了是接我专线。
|
||||
- [00:34:51 - 00:34:55] 未知说话人05: 做账客,单位的业务发展。
|
||||
- [00:34:56 - 00:35:00] 未知说话人05: 各项指标都会好,方法我也教了,也没看到动作出来。
|
||||
- [00:35:01 - 00:35:02] 未知说话人05: 也没看到回复。
|
||||
- [00:35:04 - 00:35:09] 未知说话人05: 请今天要给我一个具体的回复,哪个能保证那项指标达成?
|
||||
- [00:35:13 - 00:35:15] 未知说话人05: 中心上,其他我就不说。
|
||||
- [00:35:19 - 00:35:22] 未知说话人03: 关于那个市场部的工作说。
|
||||
- [00:35:22 - 00:35:25] 未知说话人03: 三个方面,一个方面就是。
|
||||
- [00:35:26 - 00:35:29] 未知说话人03: 整个一个资料的一个通窗牌,就是。
|
||||
- [00:35:29 - 00:35:33] 未知说话人03: 一个是本季度的一个收官不足。
|
||||
- [00:35:34 - 00:35:36] 未知说话人03: 刚才盘点了,按照目标来推。
|
||||
- [00:35:38 - 00:35:42] 未知说话人03: 治疗的第2个像小方面,都是基本上那个周也是。
|
||||
- [00:35:43 - 00:35:44] 未知说话人03: 最后1周了。
|
||||
- [00:35:45 - 00:35:56] 未知说话人03: 本本季度都是新主营销不厚,我觉得完了过后还是有一些按部就班的一些,就大家有点疲,包括那个整个业务推进,市场方面也比较疲软。
|
||||
- [00:35:57 - 00:35:59] 未知说话人03: 请商务部提前谋划。
|
||||
- [00:35:59 - 00:36:03] 未知说话人03: 二级部的一个业务活动,要把生势做。
|
||||
- [00:36:04 - 00:36:06] 未知说话人03: 不能说二季度是传统的淡季。
|
||||
- [00:36:08 - 00:36:17] 未知说话人03: 不管是我的签约也好,3人也好,H也好,还是那个AI终端也好,那个业务活动的那个声势还是要造起来。
|
||||
- [00:36:19 - 00:36:19] 未知说话人03: 老三不提。
|
||||
- [00:36:21 - 00:36:27] 未知说话人03: 第2个方面就是那个,上周那个,根据我看那个能力地图、收入地图已经发过来了。
|
||||
- [00:36:28 - 00:36:31] 未知说话人03: 请那个市场部和渠道中心。
|
||||
- [00:36:32 - 00:36:33] 未知说话人03: 馆主。
|
||||
- [00:36:34 - 00:36:39] 未知说话人03: 本周内,把涉及到销售能力的几个事情的进度。
|
||||
- [00:36:40 - 00:36:43] 未知说话人03: 给我做1次报告,一个是招聘的情况。
|
||||
- [00:36:44 - 00:36:46] 未知说话人03: 第2个是农村渠道的那个。
|
||||
- [00:36:47 - 00:36:51] 未知说话人03: 进度,第3个是上周行销那个事情。
|
||||
- [00:36:52 - 00:36:53] 未知说话人03: 还没来一个。
|
||||
- [00:36:53 - 00:37:00] 未知说话人03: 具体的方案,营销队伍建设和转型,本周内给我一个这三个事情。
|
||||
- [00:37:00 - 00:37:02] 未知说话人03: 只做1次汇报。
|
||||
- [00:37:03 - 00:37:04] 未知说话人03: 三个事情满意度。
|
||||
- [00:37:06 - 00:37:10] 未知说话人03: 满意度,这1次满意度的测评结果,上周五,林哥说了个号。
|
||||
- [00:37:13 - 00:37:17] 未知说话人03: 我当时不还是觉得这个事情不管错我还是。
|
||||
- [00:37:18 - 00:37:22] 未知说话人03: 市场部和政企部,这个工作确实是。
|
||||
- [00:37:22 - 00:37:23] 未知说话人03: 有舒服。
|
||||
- [00:37:27 - 00:37:32] 未知说话人03: 这次是那个,就是只应该是最后,就是按照老的方式来测评嘛。
|
||||
- [00:37:33 - 00:37:35] 未知说话人03: 下一个就是用拿用户基评来测评。
|
||||
- [00:37:36 - 00:37:37] 未知说话人03: 3月份还有。
|
||||
- [00:37:38 - 00:37:41] 未知说话人02: 那近期就没机会了。哎,近期不会再出。
|
||||
- [00:37:44 - 00:37:48] 未知说话人03: 所以说这个事情,我觉得,大家真的要反思一下。
|
||||
- [00:37:49 - 00:37:52] 未知说话人03: 满意度的工作你是做了吗?还是做大了?
|
||||
- [00:37:55 - 00:38:10] 未知说话人03: 正起步之前都是我们满意度一个拉分项,一个开卷考试。廖经理是不是思想上松懈了?因为除了霞总参加的客户会我看到廖经理之外,其他次的客户会廖经理都不在。
|
||||
- [00:38:11 - 00:38:14] 未知说话人03: 都是一个,都是一个活开卷儿噻。
|
||||
- [00:38:15 - 00:38:19] 未知说话人03: 我觉得这个事情你应该是可控的,你才不,你才不关注这个事情。
|
||||
- [00:38:23 - 00:38:25] 未知说话人03: 补充句,自己不要主观对这个。
|
||||
- [00:38:27 - 00:38:30] 未知说话人03: 除了廖经理以外,你们哪个主管对正气满油负责?
|
||||
- [00:38:31 - 00:38:32] 未知说话人03: 不能只是后开学吧。
|
||||
- [00:38:34 - 00:38:40] 未知说话人03: 我上周我就跟廖经理说的,如果说后开学这个工作抓不起来,让他亲自抓。
|
||||
- [00:38:50 - 00:38:51] 未知说话人08: 麻烦等会儿那个。
|
||||
- [00:38:52 - 00:38:59] 未知说话人08: 我觉得现在就是叫啥子啊?亡羊补牢为时未晚。这个事情现在还有。
|
||||
- [00:39:00 - 00:39:03] 未知说话人08: 还有时间,但是我觉得市场不合适。
|
||||
- [00:39:05 - 00:39:17] 未知说话人08: 在抓这个工作的时候,老是出了问题才重视,才才反转,才抓微笑曲线。我觉得这种工作方式和工作态度,我觉得我们要反思一。
|
||||
- [00:39:17 - 00:39:23] 未知说话人08: 另外就是关于那个,就是客服的工作,中周末的时候,我也跟那个。
|
||||
- [00:39:24 - 00:39:28] 未知说话人08: 内部的领导做的沟通,有几点。
|
||||
- [00:39:28 - 00:39:31] 未知说话人08: 也是同步市场部,也是给夏总做了一个会议。
|
||||
- [00:39:32 - 00:39:35] 未知说话人08: 就是那个第1个,就是八零的两绿。
|
||||
- [00:39:36 - 00:39:42] 未知说话人08: 就是到3月底,特别是3月底,就这个话关起门来说,四公司会有统一的。
|
||||
- [00:39:44 - 00:39:48] 未知说话人08: 是我们是汇通运营,所以说就是他的满意的样板儿。
|
||||
- [00:39:48 - 00:39:58] 未知说话人08: 下来就是你跟那个小付一起在我办公室,我们讨论一下,满意就是客户满意的样本,一定要按照四公司的规定来。
|
||||
- [00:39:58 - 00:40:01] 未知说话人08: 第2个是对于不满的客户。
|
||||
- [00:40:03 - 00:40:08] 未知说话人08: 它有两个时间节点,一个是五点半,一个是六点五点半过后。
|
||||
- [00:40:08 - 00:40:29] 未知说话人08: 还有六点半有几个操作的一个有个技巧,同时不满的客户要报给客户,因为现在不是这个指标不是KPI考核了集团的,但是哎总是要求的,要考核分公司的,所以说这个事情在操作上面是有空间的。
|
||||
- [00:40:32 - 00:40:35] 未知说话人08: 然后那个八零两的我也看。
|
||||
- [00:40:36 - 00:40:41] 未知说话人08: 小孩治疗,我们目前是属于一类的倒数第2的左右。
|
||||
- [00:40:42 - 00:40:52] 未知说话人08: 也是,也是不是低于全市的平均?所以说,我觉得这个事情也是没有快速的把市公司的有一些技巧性的动作吃透。
|
||||
- [00:40:58 - 00:41:02] 未知说话人08: 好,在考牌上面都是发的两对,是有打印后面的。
|
||||
- [00:41:04 - 00:41:06] 未知说话人08: 这个是可以,是可以来平衡的。
|
||||
- [00:41:08 - 00:41:10] 未知说话人08: 好,这块儿的话就是请那个。
|
||||
- [00:41:11 - 00:41:19] 未知说话人08: 市场部把每天的那个,就是每天都是到月底之前,每天红星上面出个日报。
|
||||
- [00:41:21 - 00:41:23] 未知说话人08: 发送给发给我个下头嘛。
|
||||
- [00:41:25 - 00:41:28] 未知说话人08: 然后考关于考核,我也大概问了一下。
|
||||
- [00:41:29 - 00:41:32] 未知说话人08: 802月还是与那个,就是有可能有提高。
|
||||
- [00:41:33 - 00:41:39] 未知说话人08: 有可能又不高,也没说定。今年的KPI考核基本上定了,是工信部的有责。
|
||||
- [00:41:40 - 00:41:53] 未知说话人08: 要考K牌,还有就是离网率,就是跟满意度相关的,就是客户不走,就是艾总的一个观点,驾驶提升,就离网率不高于去年,也应该是个,也应该是会拿个K牌考核。
|
||||
- [00:41:57 - 00:41:59] 未知说话人09: 应该是一个,就是。
|
||||
- [00:42:00 - 00:42:04] 未知说话人09: 目前都是定了的,就是两个考核,一个是工信部有责,一个是。
|
||||
- [00:42:04 - 00:42:05] 未知说话人09: 当时。
|
||||
- [00:42:06 - 00:42:10] 未知说话人08: 八零两玉是八零两玉是有打印。
|
||||
- [00:42:11 - 00:42:23] 未知说话人08: 大概是这个样子,所以说就把那个考核的情况,你进一步再去摸细,还有那些都是可以可控的操作的一些动作。
|
||||
- [00:42:23 - 00:42:25] 未知说话人08: 跟死工说话。
|
||||
- [00:42:27 - 00:42:32] 未知说话人08: 对吧?市场部都说的三个方面,综合部的话,这边就是他运动会本周的运动会。
|
||||
- [00:42:33 - 00:42:34] 未知说话人08: 对,朱子豪。
|
||||
- [00:42:35 - 00:42:41] 未知说话人08: 我是星期给下边大了喂,星期三、星期四要出差,星期五到时候。
|
||||
- [00:42:43 - 00:42:51] 未知说话人08: 然后有啥事情,就是给我报告的事情。如果是来得及的话,就明天明儿下午,俺说几个事情。
|
||||
- [00:42:53 - 00:42:58] 未知说话人08: 跟我汇报,如果来不及的话,就就约视频。好,星期五上。
|
||||
- [00:43:06 - 00:43:07] 未知说话人10: 工作两个领导。
|
||||
- [00:43:11 - 00:43:12] 未知说话人11: KPI。
|
||||
- [00:43:13 - 00:43:18] 未知说话人11: 刚才会上我们也过了1遍,按照我们定好的目标,确保完成。
|
||||
- [00:43:20 - 00:43:22] 未知说话人11: 好,满意度的话。
|
||||
- [00:43:22 - 00:43:25] 未知说话人11: 具体的一些情况,请你们这个会后。
|
||||
- [00:43:27 - 00:43:28] 未知说话人11: 一个详细汇报。
|
||||
- [00:43:29 - 00:43:30] 未知说话人11: 我想强调的是。
|
||||
- [00:43:32 - 00:43:32] 未知说话人11: 自信的我。
|
||||
- [00:43:34 - 00:43:37] 未知说话人11: 我觉得不管是部门儿还是。
|
||||
- [00:43:38 - 00:43:46] 未知说话人11: 不管是部门经理,还是主管,还是具体抓工作的人,和每一个一线的同志们,大家都要有那个执行力。
|
||||
- [00:43:47 - 00:43:50] 未知说话人11: 事情要把事情做好。
|
||||
- [00:43:52 - 00:43:54] 未知说话人11: 要知道怎么做,但是就是不去做。
|
||||
- [00:43:56 - 00:43:58] 未知说话人11: 那我觉得那是我们公司至少。
|
||||
- [00:43:59 - 00:44:03] 未知说话人11: 我们班子几个人是,我相信都不认可的那种工作风。
|
||||
- [00:44:10 - 00:44:12] 未知说话人11: 好,还有市公司的那个年度考核。
|
||||
- [00:44:13 - 00:44:18] 未知说话人11: 觉得几个部门都要去了解情况,那个提前也给你们都说过几次。
|
||||
- [00:44:19 - 00:44:20] 未知说话人11: 如果有。
|
||||
- [00:44:21 - 00:44:24] 未知说话人11: 对我们影响比较大的一些病毒,或者是。
|
||||
- [00:44:25 - 00:44:33] 未知说话人11: 你要提前讲,不要等到起那个,别个都定好了再来给我说,夏总,那个考核今年这种我们要招工。
|
||||
- [00:44:34 - 00:44:35] 未知说话人11: 对我说很。
|
||||
- [00:44:37 - 00:44:42] 未知说话人11: 我们把工作坐在前面,你们细了解。我其实有点担心两个,一个是。
|
||||
- [00:44:43 - 00:44:45] 未知说话人11: 那个叫啥子?那个阿布考克。
|
||||
- [00:44:46 - 00:44:52] 未知说话人11: 那个全市那个集团公司有一个啥子 app 提升啥子考的,我不知道他怎么考,我不清楚。
|
||||
- [00:44:53 - 00:44:54] 未知说话人11: 他是个。
|
||||
- [00:44:55 - 00:44:57] 未知说话人11: 提升或者改善或者啥,他不的啥子。
|
||||
- [00:44:58 - 00:45:01] 未知说话人11: 我觉得那个对公司,公司我不知道会不会有。
|
||||
- [00:45:02 - 00:45:10] 未知说话人11: 我们要去,不管哪个样子,我觉得考核,我其实我们不要求市公司,好像要对各分公司有啥子。
|
||||
- [00:45:10 - 00:45:17] 未知说话人11: 不要去想那些事情,但是至少是比较公平的。我们通过努力,我们可以去进行一个得分儿改善的。
|
||||
- [00:45:18 - 00:45:19] 未知说话人11: 制作单位。
|
||||
- [00:45:20 - 00:45:22] 未知说话人11: 你们提前沟通,我那边的话也会。
|
||||
- [00:45:24 - 00:45:28] 未知说话人11: 好,两个分管领导那边的话,也跟他们两个主要部门嘛,政企部跟。
|
||||
- [00:45:29 - 00:45:35] 未知说话人11: 反正我们加强那个嘛,然后如果确实有必要的话,我们可以去。
|
||||
- [00:45:35 - 00:45:36] 未知说话人11: 被使用。
|
||||
- [00:45:36 - 00:45:37] 未知说话人11: 好,那些沟通。
|
||||
- [00:45:39 - 00:45:50] 未知说话人11: 是一个联动的一个非常重要的一点,不要开始都不处在起跑线上,那个很麻烦。不像我印象,我们当时那个靳思还在有1年说,我们那个啥子。
|
||||
- [00:45:50 - 00:45:52] 未知说话人11: 心也不靠哎,是吧?
|
||||
- [00:45:53 - 00:45:58] 未知说话人11: 开始都是主要在起跑线上面,最开始我为哈子不沟通清楚那种考的口径和那些?
|
||||
- [00:45:59 - 00:46:08] 未知说话人11: 是吧?我相信市公司它也应该会考虑分公司的整体情况,然后拼出来,至少大家都能够调高没得多,是吧?
|
||||
- [00:46:14 - 00:46:16] 未知说话人11: 今天周会在那儿结束。
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "新会议",
|
||||
"created_at": "2026-05-08 17:36:41",
|
||||
"original_filename": "文件会议 05-06 13_37-Transcript-2.md"
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
# 文件会议 05-06 13:37 会议转录
|
||||
|
||||
- 会议时间:2026-05-06 13:37:48
|
||||
- 主持人:AlanPaine
|
||||
- 导出时间:2026-05-08 10:51:11
|
||||
|
||||
## 转录正文
|
||||
|
||||
- [00:00:01 - 00:00:05] 未知说话人01: 也是我们也对宽带的重视,也是有一定的效果。
|
||||
- [00:00:06 - 00:00:37] 未知说话人01: 然后上门处理,因为上周第1个是下雨的原因,第2个导致的安装的上门的量的下降,所以当周的那个上门量还是比较高580。所以说那个累计上门量达到了以前以上,但是离我们的目标3000户的话这一块,稍微进度还是靠后,主要还是因为上门这块和那个,和安装这块的平衡,要两边都要兼顾。总体的话,线路故障的话这一块是比较平稳。
|
||||
- [00:00:37 - 00:00:42] 未知说话人01: 你那个说法,刚刚说的本来那个安装没得好多量的噻。不是没得量,下雨。
|
||||
- [00:00:43 - 00:00:58] 未知说话人01: 下雨打的,上周下雨。上面都应该黑皮的啊。上面就比较好的,咱们这上面比较好的。那整个加在一起的话,你才。前面我们不是。累积了35的进度,那个进度不高哦。前面2周不是安装达到了1000吧,最近。
|
||||
- [00:00:58 - 00:01:02] 未知说话人01: 你给我看后面,我们这上周我们安装只有接近400。
|
||||
- [00:01:02 - 00:01:17] 未知说话人01: 所以说这个安装量和上门量,它两个还是就是每1周还是达到了将近1000的上门量,就是安装和维护的上门还是有1000,然后每个月的四达到了4000的上门量,然后再看一下那个。
|
||||
- [00:01:17 - 00:02:06] 未知说话人01: 这个刚说的就是那个上门整个指标的情况的话,就是从上门之后的指标几个关键指标,第1个是弱光,弱光现在目前是0.51,也是在上周持续在向好,即将达到0.5的那个目标。三代终端也是因为全年因为去年的目标是7.5,今年要求的年度目标是5.5,所以说这个需要一个持续往下压的过程,这个也是较上周提升了0.1个百分点,就是下降了,就是有改善。所以说这个是年度目标的话,我也跟司空建议了,这个指标它会拉入到运维,我也建议他们那个每一个季度设一个阶段性的目标,不然的话全市的话5.5都达不到现在目前。FPTR现在是达标了,就上周这块,那达标,主动过境这块是靠后,0.3,这是一个上门之后的效果。
|
||||
- [00:02:07 - 00:02:40] 未知说话人01: 然后那个九零工程转化率要达到90%,退单率要低于7.5。然后整个月度来看的话,我们现在是转化率是87.35,离90的目标还差一点点。但是当周来看的话,主要是天气影响啊。当周的虽然上了80%,但是离90的目标还是差的很远。但是月度来看的话,都是转化率还是有很大的提升,接近90,退单率是6.53。整个退单的那个改约的情况是影响那个转化率的一个主要因素,主要是用户原因29单,覆盖6单,天气2单。
|
||||
- [00:02:41 - 00:02:47] 未知说话人01: 整个退单来看的话,主要是用户不安装退单16单卡,长期无法连续3单。
|
||||
- [00:02:48 - 00:03:06] 未知说话人01: 还有入错4单,低价值入错建设,用户入网不通,这块。三块蓝单的话,就是上周的话,那个没达到80%,56.82,整体的当月的转化率是75.29,也是比八十还是稍微还差一点的,退单率是44.29。
|
||||
- [00:03:07 - 00:03:51] 未知说话人01: 然后退单率比较高的原因,主要还是那个B to C的这一块的那个协调问题。这块一个是审核,撤单的退单的流程审核已经给施工是那个建议了。当时那个院里经理也专门跟我打电话,他也是明白了我们想做的那个这个审核的一个流程意识,他们也在正在开发。然后同时的话,也那个这个指标也会是我们综合运维的一个考核指标。我们也建议了施工是上次来也建议他们这个退单率应该看能不能提出这种分居长,如果这种一线审批如果同意了,我觉得还是应该提出的啊。不然的话,这种团单来了之后啊,都是他自己有一些个人的意识在里面,要退单啊。
|
||||
- [00:03:53 - 00:04:21] 未知说话人01: PCDN那个专线持续在恶化,然后主要还是学校,就是当月3月份的话是开学之后啊是4.84,这个的话一个就是我们把那个涉及到的IP地址已经报市公司帮我们分析这个出口的学校的IP地址,因为目前数据我们上周跟他们沟通之后他们现在这1周才能反馈那个,啊是集中在一个学校吗?两个学校,人文和是海南还是,就两个学校。
|
||||
- [00:04:22 - 00:05:31] 未知说话人01: 我但这个我报全职以后,他是不是马上就会过限速啊?呃,他是要把IP地址分析出来之后,要报给学校限速。学校他们现在也在协同他们。啊。我们。我们也在找全职,他们能不能帮我们后来限建立这种机制?因为三关,因为加关和启关现在都已经都施工都不通报了,周报也没有了,主要是现在主要问题还是在专线。问问题是专线主要还是在学校我们。学校的话,因为我们只是提供他的出口带宽,他的IP地址啊那些数据的话,要经过那个。而且学校的话互联网带宽我们是没收费的。对免费。这个是更不应该出现问题了。哎,这个他们这个学校这边的话,如果有问题,我觉得第1时间就应该直接就在系统上限。对,我们也在想这个是正常的这个行为。我们也想在那个。学生在沟通一下嘛。一旦发现直接限掉,他也没什么好说的。他作为一个学校,或者是那个什么,他那个提供的是正常的那个带宽使用的这个速度。如果他那个这个超过了这个的话,那这是有问题啊。我现在学校全职,尽快的话看有没有
|
||||
- [00:05:33 - 00:05:41] 未知说话人01: 这是整个那个PCN啊,3次空间主要1项没达标,主要就是那个物业点那个本月那个。
|
||||
- [00:05:42 - 00:05:49] 未知说话人01: 那个之前是计划的本月,但是反馈天线还现在没有过,预计4月初进行一个检测轨道。
|
||||
- [00:05:50 - 00:05:52] 未知说话人01: 其他的都是达标的。
|
||||
- [00:05:53 - 00:06:28] 未知说话人01: 然后唱厅有1项,主要是那个,其实问题都解决了,但就是要带智能体,要智能判断,剩余工单要逐项的核查是否达标才能算结束。所以说虽然是处理了,但是要等到质检,其他指标都是达标的。然后还有1个有12项自行工作啊,智能添加的,就是也包括南中也的反馈,就是我们有些打接电话没有接到。然后他们也是,当周的现在目前的解决方案是,爱立信5G基站参数的调整试点,带观察效果,这个近期反映的就是有漏话,这种情况比较多,5G这一块。
|
||||
- [00:06:32 - 00:07:03] 未知说话人01: 然后那个畅想这块全部达标,就结束了。然后,那个超频站点的攻坚这块是控制还是比较那个,有帮助。就是上周我们发现了三个超频基站,呃有两个原因是铁塔的开关电源故障导致电流过稳,所以说也及时的处理,就进行了一个恢复。然后还有1个就是传输光纤过大,这个维护部人员更换前厅后恢复,这个也是说把它解决了。然后旁站的故障的话也持续在也是处理也比较低。
|
||||
- [00:07:03 - 00:07:56] 未知说话人01: 然后专线护航目前来讲的话,118条专线我们目前的话有存量的73条的话,已经完成巡检56条,还有17条。然后未验收的工程已经建设的有45条全部进行了巡检。然后四公司要求是3月底全量完成巡检,目前17条的话,我们在月底能够按时进行一个全部巡检来完成。然后主要是那个涉及到存量这一块,我们立即力改都改了,主要还是涉及到光缆路由的这块有抢台行动,我们会及时的上报给四公司。然后上周的话我跟机科里面的培训,客服出了问题主要还是他们内部的那个,就是他们的机房和机柜这块的问题比较严重,这块也是。今天我们会就是这1周的话这2天会把全量的清单,我们的问题客服处理的问题全量的发给客服经理,让他们知晓并与客户沟通。
|
||||
- [00:07:57 - 00:08:04] 未知说话人01: 然后当周故障的话是收到报障是33件,然后9件跟网络相关,主要问题还是光缆这块的问题啊。
|
||||
- [00:08:07 - 00:08:13] 未知说话人01: 然后东环呢也持续保持一个良好的一个水平,上周还在全市做了一个那个交流。
|
||||
- [00:08:14 - 00:08:53] 未知说话人01: 金沙管家这一块重点,那个说一下二级,因为上周小总也安排了二级。二级的话,整个我们目前,就最新的数据,我们现在剩下20206年总共还剩下一百二十一站,这二百一百二十一站其实上周也是抓紧处理,已经全部下电了。然后目前累计完成拆除是四十六站,还有75站。七十五站预计的话,我们争取的话是在2周之内完成全量的拆除,然后进行只管专署以及电量服务费4月的一个调整。也就相当于在4月15号之前可以全量完成二级的拆除和下电和服务费的调整。
|
||||
- [00:08:55 - 00:09:04] 未知说话人01: 好,工程下层项目都很正常,除了那个他们那个单子也在补当中。
|
||||
- [00:09:06 - 00:09:08] 未知说话人01: 然后其他的就是也都是正常开展的。
|
||||
- [00:09:09 - 00:09:12] 未知说话人01: 其他就是没有啥子大的问题啊。
|
||||
- [00:09:12 - 00:09:35] 未知说话人01: 还有就是最后一个就是网络质量综合评估体系,虽然没有发文,但是已经给已经发下来了。那个我们内部先收到了,这一块我们会,嗯后面就是下1周的话我们会针对综合网络运维评估体系进行一个那个进行一个分解和目标的一个制定啊,这边就没有起来了。
|
||||
- [00:09:46 - 00:10:00] 未知说话人02: 25年剩余2项工作,第1个花果山那个没得啥子变化的,第2个微托无人机,是说的在金南人组织验收以后,是花本周哈拜访唐书记进行推动,是项目组的一个。
|
||||
- [00:10:01 - 00:11:03] 未知说话人02: 上周完成了5项工作,包括嗯这种要求,建委哈对施工司管的框架下整理的工作清单,以及投资计划专项评估汇报,建委部答复是已经汇报,并且完成。然后市场那块终端占比问题,嗯是进行了一个全方位工的一个重点的一个汇报,形成了一个五个方面哈制定了具体的措施,嗯解决问题,最终又提升啊,答复是已经进行了专题研讨汇报。,正中安排的收入地图和行业中心的收入地图,是各中心已经完成,并且经嗯要求进行了提交,中核集团。,打印机哈那块是跟局科到现场办公室沟通以后,现在已经是收回中国国,啊专门为我们嘞调度表哈预留1.1元个打印机。同时啊那块我们也在思考哈如何确保,了解了他们日常需求的嗯打印数量,嗯打印情况以后,嗯我们在周边的哈打印店也进行了一些洽谈。
|
||||
- [00:11:04 - 00:11:27] 未知说话人02: 最终他们的价格偏差还是很大,有十倍以上。啊,最后我们嗯跟建,跟那个叫啥,整整套是吧?啊,整套。啊,整套。沟通以后,到时候我们去试,他有需求的时候,我们陪到一起去试,确保质量的情况下,我们呃提供一个相当于外派点,进行一个保障,确保那个招投标的打印,不影响招投标。
|
||||
- [00:11:28 - 00:11:29] 未知说话人02: 那个气象。
|
||||
- [00:11:30 - 00:11:42] 未知说话人03: 那个事情给那个行业中心和那个,运输中心都说,都是个人自己要晓得哦,下回不要再给我,再给我以那个理由,再说去答应你有问题,那都是个人的问题。
|
||||
- [00:11:43 - 00:11:45] 未知说话人03: 请你们通知到位,好吧。
|
||||
- [00:11:48 - 00:12:39] 未知说话人02: 然后有7项工作人,在推动过程中。第1个是前期交办的预期数据中心哈整体包装,那块儿是说政府要拿出方案,补贴方案以后的话,再汇报。,无人机哈那个需求,结合到落实成为合川本地的一个方案,目前没得啥子变化和之前的反馈。,然后基建工程两个宣传工作计划,中国那边在推动基建工程两个是,留言后,目前还没下发以后,我们在优化制定。啊,宣传工作那块儿目前说之后,争取本周完成一个,那个嗯推动啊,因为工作人兼职的原因啊。然后那个嗯渠道那块儿呢,有一个产能评估,那块儿是计划,嗯开了宣传会,嗯还在梳理方案,最后是结果情况,预计在本周进行一个专题汇报。,专线发展节奏的问题,希望整体思考,整体将。
|
||||
- [00:12:40 - 00:14:53] 未知说话人02: 那个数据进行了展示,然后嗯体现的是整体情况,本周专题汇报。,然后分局是那个资产优化的运输类的话,是形成了那个清单周报。,然后那个每周与分局进行沟通,形成一个清单的一个呃计划,啊具体的优化方案,嗯完成以后哈进行一个完结,那是在跟进的效果。呃,综合当前几点有1条有些做的工作,请大家知晓。呃,3月20号我们也召开了分公司的话,呃工会主席面对面哈进行了一些沟通,一个是我们的工会经费进行一个公示。啊,因为整个工会经费哈从市工会到市公司哈再到分公司都有所压减,啊所以今年我们需要一记严考用更少的钱哈办更好的事儿。然后主席给我们做了一些具体指引,大家有啊积极发言。同时今年我们在本周需要上报市公司的软性工程,嗯其中我们已经确定的啊可以上报哈目前沟通的,包括我们更衣室哈包括我们食堂的改造。食堂改造那边的话,嗯按照之前的方案是大概是29.80000,然后我们将会进行一个审计。呃结合到大家用餐的时间,我们提出的建议是5月哈结合
|
||||
- [00:14:54 - 00:15:20] 未知说话人02: 更替和修补。呃,同时呃,市公司呃呃,和分公司,我们做了解以后,也是收集大家意见以后,包括啊,我们准备呃引用那个自饮机的方式哈来解决我们用水的问题,送水啊那些呃机器也坏了,自饮机那块儿的话也报了市公司,对批准,等到去批复以后啊,我们就可以引入,大概在下半年的时候,我们就可以用自饮机哈进行饮水,同时也节约成本。
|
||||
- [00:15:21 - 00:17:07] 未知说话人02: 幸福一家一的活动,全年同时组织了六场啊大型活动啊,包括3月的运动会啊,4月的足球,5月的羽毛球,6月的篮球,10月的气排球和10月的乒乓球。啊,分公司对于除了参加四公司活动以外,整体还安排的有一些重大节假日的一些活动,包括近期我们啊在思考筹备的6月二中节啊的一个活动,以及我们那个啊班组活动,班组活动那边的话也是整出了大家的意见,可能今年我们也在思考是不是搞一个我们分公司内部的班组之间的啊嗯气排球比赛啊,通过那种形式哈来解决那个啊班组各自开展活动哈那种另行开展的那个方式,然后根据的一些啊就是在一个思考过程中。嗯同时重点汇报一下周5哈计划的是第4届体育嗯文化节,啊我们河川将以河川佳节哈穿越巅峰,一起新嗯一起新城,然后动要赛场哈一个主题口号,结合到我们泡竹汤哈啊出名的一个形式,通过我们方正和演员的演出,将我们啊深情的河川的那种啊快乐啊热情的那种精神面貌哈展示给全市的啊兄弟公司和领导
|
||||
- [00:17:08 - 00:17:16] 未知说话人02: 原来黄翔啊,他们都是因为啊有伤在身啊,无法参加。啊,他们觉着不行啊。啊,他不得行。
|
||||
- [00:17:17 - 00:17:21] 未知说话人02: 这是哪儿受伤了啊?呃,他肌肉拉伤。
|
||||
- [00:17:23 - 00:17:26] 未知说话人02: 没法成交吗?哎,对,他不敢跑,对吧?
|
||||
- [00:17:27 - 00:17:30] 未知说话人02: 方向啥情况啊?呃也是。
|
||||
- [00:17:31 - 00:17:37] 未知说话人03: 两个主力选手都不得行哦,那个今年是那个有点儿具体哦,平时主持体格。
|
||||
- [00:17:38 - 00:17:40] 未知说话人02: 他是那么跟我说的。
|
||||
- [00:17:41 - 00:17:43] 未知说话人03: 我29,然后他们七八。
|
||||
- [00:17:44 - 00:17:48] 未知说话人03: 看得起啊,我说没看得起黑老婆呀。
|
||||
- [00:17:48 - 00:17:56] 未知说话人02: 他不敢爆发性的发力,那种。如果是,如果是确实受伤了,我觉得吧,就不能勉强,因为我。
|
||||
- [00:17:58 - 00:18:54] 未知说话人02: 好,然后完了以后的话,就是需要各部门儿积极配合,特此请示领导。一个就是我们方阵,目前除了我们参赛的队员儿和我们,呃和本人哈作为方阵队员儿以外,可能我们容纳到二十个人来进行那个活动开展。,再加上领导和一个举牌手和一个那个形象,嗯大师以外,我们一共需要25人。好,我们确定的呃报名人数以外的话,我们还差九个人,还差九个人的话看,呃结合到那个一线生产工作嘞繁忙,嗯那个过度,嗯看是不是各部门儿再出两个人。啊,构成我们8人的方阵哈另外AI运输中心出一个人,我们总共目前差九个人。啊,确定人员的话需要今天确定,确定以后我们需要给他们购买衣服。啊,购买衣服以后周二到周四进行排练,啊就是下班以后,然后星期五都去参加活动。好,那块儿的话看领导觉得合适那种分配。
|
||||
- [00:18:55 - 00:18:57] 未知说话人02: 一个男生整起来。
|
||||
- [00:19:00 - 00:19:04] 未知说话人03: 电脑都没地方,每个部门两个人该出来,是这个想法。
|
||||
- [00:19:05 - 00:19:07] 未知说话人02: 周二到周四要拍的呀。
|
||||
- [00:19:07 - 00:19:09] 未知说话人02: 买了几件参加。
|
||||
- [00:19:10 - 00:19:13] 未知说话人03: 不是,确实跟到两个人都看不出来,跟我说。
|
||||
- [00:19:15 - 00:19:17] 未知说话人02: 性别性呢?呃,不行。
|
||||
- [00:19:19 - 00:19:21] 未知说话人03: 大家说清楚有衣服的。
|
||||
- [00:19:23 - 00:19:34] 未知说话人02: 同时呢,参加以后,介会我还上决赛,和往年一样,积极参加的还是有一定的绩效的,一个加分儿,只要参加,方阵的是每人一分儿,获获得名次的啊更多一些。
|
||||
- [00:19:36 - 00:19:50] 未知说话人02: 好,第2个都是,请知晓今天的主题教育,公司也是啊已经发布了第1期的教育简报,啊总体来说都是第1期就是公布公司,啊在召开了主题教育的专题的一个那个啊工作。
|
||||
- [00:19:51 - 00:20:05] 未知说话人02: 好,第2个基层党组织,就是上次我们也开了,截止到3月15号,所有的基层党组织也开展了学习,后面我们再按照其那个动作来执行。好,因为呃主题教育,请大家知晓动作。第2个都是,市公司也要求。
|
||||
- [00:20:06 - 00:20:34] 未知说话人02: 招待费哈要进行一个信息公开,那块儿公开的对象和范围啊,都是本单位嗯管理层的那个嗯班子成员,那个范围。所以前期我们也是通过邮件的方式将25年啊,啊招待费的形式进行一个发布和公示,也完成了向纪检组织的啊报备。好,请领导知晓,这项工作已经完成。等我问一下,它那个公开是每年公开1次吗?还是每1次都要公开呀?每年1次,现在每年。
|
||||
- [00:20:38 - 00:21:59] 未知说话人02: 好,然后那个25年整体招待费使用的情况,嗯那个嗯也嗯做好做个汇报,25年,我们整体招待费的使用是超我们年初预算是14%,其中综合部哈是逐年增长,24年、25年哈逐年增长,嗯增长去非常明显,超预算也非常多,我们综合部去年超了107%,好所以26年的话也给综合部调整了预算,其他部门因为涉及到成本的管控,目前没有调整预算,嗯26年使用来看的话,目前也是综合部,嗯以及我们的市场部,市场部因为年初的渠道大会,啊整体它的那个时间节奏可能不太一样,包括我们超改分局和南京的分局,相对使用较快,是超过了时间进度,好其他一些部门的招待费预算力度啊,是是在进度范围之内,好可能更多的嗯要进行嗯特别提醒嘛,我觉得提醒啊整体可以嗯其实是有钱,在那个一个范围之内可以合理的规划,按时间进度哎,安排更多的同志,参与的同志都可以报,包括嗯因为之前我们也盘点的,嗯那个包括安运输中心
|
||||
- [00:22:00 - 00:22:09] 未知说话人03: 情况的一个汇报和通报。看到的,给我说一下,就是关于政企部啊,因为我们的整个对外招待,集福来政企部啊。
|
||||
- [00:22:10 - 00:22:15] 未知说话人03: 这起步那边的话呀,因为有些重要单位又集中在个别的客户经理那边儿。
|
||||
- [00:22:16 - 00:22:19] 未知说话人03: 所以说这种啊,要经历比较统筹。
|
||||
- [00:22:20 - 00:22:23] 未知说话人03: 那个统筹安排,你不能说一个客服经理。
|
||||
- [00:22:23 - 00:22:41] 未知说话人03: 太多,是吧?然后比如说,有像那种的,比如哎,服务中心的那边的街坊啊,那些也可以,就大家分到来,那边你跟和谐商量,把那个,就说实在去,是真实发生的费用啊,尽快的解决和。
|
||||
- [00:22:43 - 00:22:46] 未知说话人03: 不要拖,然后据我了解,去年子还有些费用都没还没完。
|
||||
- [00:22:47 - 00:22:49] 未知说话人03: 今天是油来了,是吧?
|
||||
- [00:22:49 - 00:22:56] 未知说话人03: 那个事情呢,我认为它是个,不是个啥子大事情,不需要喊我们那个公司领导市民来操心的那个事。
|
||||
- [00:23:01 - 00:24:22] 未知说话人02: 然后河川区发了一个通知,叫做河川区担当作为先进集体和先进个人。因为之前我们也报过河川强区啊企业的先进集体、先进个人,好目前还在区领导那里已经,嗯提交区领导一个,因为目前区领导还没得指示。好同时收到弄了一个通知,嗯那个文件的话相当于之前他的那个我们区的文件内容是,嗯区级的部门儿,啊单位以及区国资委啊管辖的企业。好因为今年呢,领导班子也特别提到计划我们要逐渐在河川区啊加强,叫做呢嗯增强我们区的影响力。所以我觉得那个可能也是一个点说,我们也单独进行了一些追踪和嗯询问哈那个下发单位,不是区委办啊,府办,嗯区委组织部以及区人力社保局啊,他们组建成了专班。好联系人是委办一个通知和人力社保局,看到他们是经办的那个负责发文的同志。好相当于嗯经过咨询一个,嗯争取到相当于我们,嗯如果有意愿参加的话也可以参加。看了下前一届的那个评选名单呢,没得那种我们那种企业,都是政府的一些组织和机构。好那个
|
||||
- [00:24:23 - 00:24:40] 未知说话人02: 首先,因为它那个报名简单啊,就是报材料嘛,我们来签头写,就说看给不给合川移动一个资格啊。有那个资格的话呀,相当于可以差异化地与竞争对手拉开差距。目前竞争对手应该是对那个还是没有引起重视也没有动。啊,青云集团有三十多名。
|
||||
- [00:24:42 - 00:24:52] 未知说话人02: 有了名额嘛,去报嘛,这是他的程序。,要求的是3月31号之前,也是一个网上申请,需要进行一个报名。啊,所以用那个事情啊,下面都。
|
||||
- [00:24:53 - 00:24:53] 未知说话人02: 的回报。
|
||||
- [00:24:55 - 00:24:57] 未知说话人02: 以上是综合部的汇报。
|
||||
- [00:25:00 - 00:25:02] 未知说话人03: 他达到啥子水平才能够担当?
|
||||
- [00:25:03 - 00:25:07] 未知说话人02: 它跟我们平一样的,都是。
|
||||
- [00:25:08 - 00:25:13] 未知说话人02: 那二十个,类似于二十个方身,都是文字型的。
|
||||
- [00:25:15 - 00:25:16] 未知说话人02: 不是。
|
||||
- [00:25:17 - 00:25:25] 未知说话人02: 就说工作突成绩突出,认真负责,类似于那种的,他都是套话。所以说那种东西,它主要还是在于。
|
||||
- [00:25:27 - 00:25:28] 未知说话人02: 给不给你的革命呢?
|
||||
- [00:25:30 - 00:25:38] 未知说话人02: 负责的是尾巴还是社保局?他们是联合工作组,通知里头有尾巴和社保局两个联系单位,应该是他们两个都在。
|
||||
- [00:25:39 - 00:26:06] 未知说话人02: 相当于突出的评选都是政治忠诚可靠啊,担当过硬啊,都是套话这个。套话。哎,所以那个工作成绩突出啊,什么,整体形象好啊,然后那个纪律严明,就像强区那个一样,实际上他也是那种历史套话。啊,所以说那块儿的话,我个人觉得还是从今历史判断来看,还是要有推荐,然后你再去报,不然的话确实有点浪费。
|
||||
- [00:26:06 - 00:26:15] 未知说话人02: 那块儿是委办室叫陈红同志,然后人力资源局是叫崔磊同志,也跟他们联系了,他们说他们都是发会议的,具体经办呢。
|
||||
- [00:26:16 - 00:26:20] 未知说话人02: 收入跟那个差距。
|
||||
- [00:26:21 - 00:26:33] 未知说话人02: 没得,没问到。你要去了解噻。哎,都是可能看那块儿是正气了解。就是有。行政区可能都是,就是讲它那边主要那个方面,是吧?然后它那个是哪一个。
|
||||
- [00:26:33 - 00:26:36] 未知说话人03: 尾巴是那个。
|
||||
- [00:26:37 - 00:26:47] 未知说话人02: 对的,我都说建议争取跟能联系,因为我们问了他们的,他说我是发会议的,我不清楚,让我鼓捣他去问呢,对不?也不太高兴。
|
||||
- [00:26:47 - 00:26:52] 未知说话人03: 那个我们没得好大的那个的话,我们去花那个时间也没得好大意义的。学校的练习有。
|
||||
- [00:26:55 - 00:26:58] 未知说话人02: 我印象中好像,那是发通报的时候。
|
||||
- [00:26:58 - 00:27:05] 未知说话人03: 好像有一个员工还有个,我说你们去了解一下,如果是那种的话,我们也可以跟这边的领导先沟通一下。
|
||||
- [00:27:06 - 00:27:09] 未知说话人03: 但是我现在不晓得是哪个领导在负责那个事儿。
|
||||
- [00:27:09 - 00:27:25] 未知说话人03: 因为你至少是委办主任那个层面嘛,或者是分管那个领导嘛,去单独去了解,好吧。他们如果,如果有那个的话,我们去争取多,确实,别个都是拼的区头的,我们也不用花那个时间。
|
||||
- [00:27:25 - 00:27:28] 未知说话人03: 是吧?了解是吧?
|
||||
- [00:27:29 - 00:27:30] 未知说话人03: 今儿不是聊天。
|
||||
- [00:27:32 - 00:30:23] 未知说话人01: 那个你那个整个三期要的第2期的工作做一个,项目汇报。现在是拆迁方面,我们整个刚去在了解的,我们一些那个拆迁,目前已经完成了1145。好,整个还有呢是。,拆迁方式我们那个通过当通过那个注册那个单位上,那么逐步好那个,做510000的价值提升,都是他原来的通货,没有达到50的我们提升到50。好,那么那个会议还有里面有好多个成员都可以说那个收入。好,那么还有1个都是,就是我们办理那个比如说新业不拆迁都是2次通货,15.1元个月。我们做了两个2次通货,都是一个那个整体层面的一个拆迁。好,那么党建网拆迁都是我们的那个新增的通货。好,包括有文化套餐,好做了那个他会一笔进行算。好,就是一季度的整个拆迁是主要的,还是在通货场景,我们原来的通货没达到50的,做一些新的价值提升,说完成率啊,成绩比较好。那个是整个拆迁一个情况。好,那么在整个历史融合在这些包括上面呢,那个会议的那个政府那个啊,还是继续
|
||||
- [00:30:23 - 00:31:03] 未知说话人01: 单位上集中做的啊,是和前方在那个,还有京东他们说也有一些社区做的啊,那种家庭的清洗,和我们那个相结合嘛,两种方式做点看,看哪种效果好。因为像在社区做的啊,我们就像比如说像区委组织部家属院,建设要家属院小区,啊那种和单位客户比较集中的小区啊,我们去开展一些,一些单位上的客户,一些服务工作。啊那么在也是做的啊,本周的一个做的情况,本周做的啊一共开展了五场,啊那个落实相对较好,那个业务量的话也还是没有达到我们想要的成果好,特别是在落实上面的签约好,其他的方案的话,集资签约的板块的话,那边我在本周啊还要进行一个加强。
|
||||
- [00:31:04 - 00:31:40] 未知说话人01: 商客市场一个情况,整个商客的话,到了我们到了2月份,收入是88.5,好比上个一期增加了10000。好完成较好的是超改,那个城北和南京改增幅都上了20000,好一家农家乐出现了负两百块钱的一个情况。啊,整体个商客的一个规模情况和那个都还是比较好。啊,那个在价值拓展方面的话,我们是完成了115。好同的是第6和下一期我再把其他公司做一个展示。因为那个我们我仅分全县的问题,目前只能看到个的。好排名是找上市公司个的。好,我下一期把那个整个全市的一个排名,好做一个展现。
|
||||
- [00:31:40 - 00:31:43] 未知说话人01: 那个是整个价值拓展的一个情况。
|
||||
- [00:31:44 - 00:32:04] 未知说话人01: 他那个重点的工作啊,都在商客经理方面的话,整个,目前我们还有2个人。,那是以周为单位,周为单位,曾会流的话,那个星期他的那个基础业务只有两笔,所以说相对于较差一点。我们是以周为单位在统计,我下期把累计的嗯按累计来嘛。
|
||||
- [00:32:05 - 00:32:08] 未知说话人01: 它那个是整个材料会吧。
|
||||
- [00:32:13 - 00:32:14] 未知说话人04: 只需要。
|
||||
- [00:32:15 - 00:32:16] 未知说话人04: 我份工作还有没得?
|
||||
- [00:32:20 - 00:32:21] 未知说话人05: 在种。
|
||||
- [00:32:22 - 00:32:25] 未知说话人05: 第1次建委那边,那个几十铺。
|
||||
- [00:32:25 - 00:32:26] 未知说话人05: 之前有个那个。
|
||||
- [00:32:27 - 00:32:28] 未知说话人05: 想的也。
|
||||
- [00:32:33 - 00:32:34] 未知说话人06: 咸鱼粉。
|
||||
- [00:32:36 - 00:32:38] 未知说话人06: 每个单位长一些,大约啥子?
|
||||
- [00:32:39 - 00:32:40] 未知说话人06: 我先模仿一下。
|
||||
- [00:32:42 - 00:32:45] 未知说话人05: 第2关,然后再次接放大,是那样的。
|
||||
- [00:32:47 - 00:32:50] 未知说话人05: 就可以上清华,反正第2天你已经理了一些,我觉得能够把那个。
|
||||
- [00:32:51 - 00:32:52] 未知说话人05: 公司人也很少的。
|
||||
- [00:32:55 - 00:32:57] 未知说话人05: 进一步结合地方的改造。
|
||||
- [00:33:00 - 00:33:01] 未知说话人07: 厨房的一些。
|
||||
- [00:33:06 - 00:33:09] 未知说话人05: 第2就是,建委今年那个综合评估体系已经出来了。
|
||||
- [00:33:11 - 00:33:12] 未知说话人05: 不知道怎么了。
|
||||
- [00:33:12 - 00:33:13] 未知说话人05: 把前面。
|
||||
- [00:33:15 - 00:33:15] 未知说话人05: 疗效。
|
||||
- [00:33:19 - 00:33:23] 未知说话人05: 第2个关于正畸康复,包括运输,已经7号就说了,第1个点。
|
||||
- [00:33:24 - 00:33:25] 未知说话人05: 上海人多。
|
||||
- [00:33:26 - 00:33:29] 未知说话人05: 经理要当天处理,及时回复。
|
||||
- [00:33:30 - 00:33:31] 未知说话人05: 像刚才,中国不同宝的。
|
||||
- [00:33:32 - 00:33:36] 未知说话人05: 那个建伟部主儿,肯定是收到,跟到给我回复,把事情是完结了。
|
||||
- [00:33:37 - 00:33:40] 未知说话人05: 我们这几块儿的经理基本上也不在那个板块的站。
|
||||
- [00:33:41 - 00:33:44] 未知说话人05: 也不好意思啊,我在会议上说了,私下也说了很多次了。
|
||||
- [00:33:45 - 00:33:50] 未知说话人05: 要养成那种日清、日清日结、日结日高的好习惯。
|
||||
- [00:33:51 - 00:33:56] 未知说话人05: 就算没完成,阶段性的来沟通一下儿,有什么问题困难,我们一起来想办法推进。
|
||||
- [00:33:57 - 00:34:01] 未知说话人05: 你不能一个事情,有些工作一说几个月都还是还没做。
|
||||
- [00:34:04 - 00:34:07] 未知说话人05: 回复工作是首先回复安排工作的领导。
|
||||
- [00:34:09 - 00:34:11] 未知说话人05: 而不是去肉包的时候会不丰富。
|
||||
- [00:34:12 - 00:34:15] 未知说话人05: 我要养成好习惯,动作要推得早。
|
||||
- [00:34:15 - 00:34:17] 未知说话人05: 不好意思啊,我都不知道得罪儿童怎么。
|
||||
- [00:34:18 - 00:34:20] 未知说话人05: 我都当是我的嘛。
|
||||
- [00:34:21 - 00:34:23] 未知说话人05: 并且恢复工作一定是要量化的。
|
||||
- [00:34:24 - 00:34:26] 未知说话人05: 要有结果。
|
||||
- [00:34:26 - 00:34:29] 未知说话人05: 要有措施,要有成效。
|
||||
- [00:34:33 - 00:34:46] 未知说话人05: 第2,关于上课这个指标,我也说了很多次了,我们没看到具体的保障措施。只有最后1周了,早上班的时候也跟廖经理做了沟通,需要拿出具体可行的方案。
|
||||
- [00:34:47 - 00:34:50] 未知说话人05: 那个1月5号那天,我就说了,是结合专线。
|
||||
- [00:34:51 - 00:34:55] 未知说话人05: 助账客单位的业务发展。
|
||||
- [00:34:56 - 00:35:00] 未知说话人05: 各项指标都会好,方法我也教了,也没看到动作出来。
|
||||
- [00:35:01 - 00:35:02] 未知说话人05: 你没看到回复。
|
||||
- [00:35:04 - 00:35:09] 未知说话人05: 请今天要给我一个具体的回复:哪个能保证那项指标达成?
|
||||
- [00:35:13 - 00:35:15] 未知说话人05: 重新想啊,其他东西。
|
||||
- [00:35:19 - 00:35:22] 未知说话人03: 关于那个市场部的工作说。
|
||||
- [00:35:22 - 00:35:25] 未知说话人03: 三个方面,第1个方面就是。
|
||||
- [00:35:26 - 00:35:29] 未知说话人03: 整个一个资料的一个存储安排,就是。
|
||||
- [00:35:29 - 00:35:33] 未知说话人03: 一个是本季度,本本季度的一个收官之日。
|
||||
- [00:35:34 - 00:35:36] 未知说话人03: 刚才谈电脑,按照目标来推。
|
||||
- [00:35:38 - 00:35:42] 未知说话人03: 治疗的第2个,像小方面都是,基本上那个周也是。
|
||||
- [00:35:43 - 00:35:44] 未知说话人03: 最后1周了。
|
||||
- [00:35:45 - 00:35:56] 未知说话人03: 本本季度都是新区营销不厚,我觉得完了过后还是有一些按部就班的一些,大家有点皮,包括那个整个业务推进,市场方面也比较皮软。
|
||||
- [00:35:57 - 00:35:59] 未知说话人03: 请商户提前谋划。
|
||||
- [00:35:59 - 00:36:03] 未知说话人03: 二级部的一个业务活动,那把生日。
|
||||
- [00:36:04 - 00:36:06] 未知说话人03: 不能说二季度是传统的淡季。
|
||||
- [00:36:08 - 00:36:17] 未知说话人03: 不管是我的签约也好,商人也好,H也好,还是那个AI军团也好,那个业务活动的那个升职还是要造起来。
|
||||
- [00:36:19 - 00:36:19] 未知说话人03: 电脑上不提。
|
||||
- [00:36:21 - 00:36:27] 未知说话人03: 第2个方面就是那个,呃上周那个根据我看那个能力地图收入地图已经发过来了。
|
||||
- [00:36:28 - 00:36:31] 未知说话人03: 请那个商务部去到中心。
|
||||
- [00:36:32 - 00:36:33] 未知说话人03: 馆主。
|
||||
- [00:36:34 - 00:36:39] 未知说话人03: 本周内,把涉及到销售能力的几个事情的进度。
|
||||
- [00:36:40 - 00:36:43] 未知说话人03: 给我做1次报告,一个是招聘的情况。
|
||||
- [00:36:44 - 00:36:46] 未知说话人03: 第2个是农村渠道的。那个
|
||||
- [00:36:47 - 00:36:51] 未知说话人03: 进度,第3个是上周营销那个事情。
|
||||
- [00:36:52 - 00:36:53] 未知说话人03: 他没在一个。
|
||||
- [00:36:53 - 00:37:00] 未知说话人03: 具体的方案,西消队伍建设和转型,本周内给我一个这三个事情。
|
||||
- [00:37:00 - 00:37:02] 未知说话人03: 做个1次汇报。
|
||||
- [00:37:03 - 00:37:04] 未知说话人03: 三个字,蚂蚁多。
|
||||
- [00:37:06 - 00:37:10] 未知说话人03: 满意度这1次满意度的测评结果,上周五,林哥说了个话。
|
||||
- [00:37:13 - 00:37:17] 未知说话人03: 我当时问,还是觉得这个事情,不管从我还是。
|
||||
- [00:37:18 - 00:37:22] 未知说话人03: 商务部和政企部,这个工作确实是。
|
||||
- [00:37:22 - 00:37:23] 未知说话人03: 有烛火。
|
||||
- [00:37:27 - 00:37:32] 未知说话人03: 这次是那个,都是,应该是最后,就是按照老的方式来测评嘛。
|
||||
- [00:37:33 - 00:37:35] 未知说话人03: 下一块就是用啊,用后机评来测评啊。
|
||||
- [00:37:36 - 00:37:37] 未知说话人03: 3月份还有。
|
||||
- [00:37:38 - 00:37:41] 未知说话人02: 有前期的,没就会咯。但前期不会在错。
|
||||
- [00:37:44 - 00:37:48] 未知说话人03: 所以说这个事情,我觉得,但是真的要反思一下儿。
|
||||
- [00:37:49 - 00:37:52] 未知说话人03: 满一度的工作,你是做了吗?还是做到了?
|
||||
- [00:37:55 - 00:38:10] 未知说话人03: 正起步之前,都是我们满一做了一个拉分项,一个开卷考试。廖经理是不是思想上松懈了?因为除了夏总参加的客户会,我看到廖经理之外,其他次的客户会廖经理都不在。
|
||||
- [00:38:11 - 00:38:14] 未知说话人03: 都是一个,都是一个货开卷儿炸。
|
||||
- [00:38:15 - 00:38:19] 未知说话人03: 我觉得这个事情你应该是可控的,你才不,你才不关注这个事情。
|
||||
- [00:38:23 - 00:38:25] 未知说话人03: 补充句啊,近期不要主观对这个。
|
||||
- [00:38:27 - 00:38:30] 未知说话人03: 除廖经理以外,你们哪个主管对郑启满队负责?
|
||||
- [00:38:31 - 00:38:32] 未知说话人03: 我支持好看点吧。
|
||||
- [00:38:34 - 00:38:40] 未知说话人03: 我上次不是跟廖经理说的,如果说货款有,这个我们就抓起来啊,让他亲自抓。
|
||||
- [00:38:50 - 00:38:51] 未知说话人08: 麻烦等会儿。
|
||||
- [00:38:52 - 00:38:59] 未知说话人08: 我觉得现在就是叫啥子啊,亡羊补牢为时未晚,这个事情现在还有。
|
||||
- [00:39:00 - 00:39:03] 未知说话人08: 还有时间,但是我觉得市场不和自己。
|
||||
- [00:39:05 - 00:39:17] 未知说话人08: 在抓这个工作的时候,老师出了问题才重视,才才反转,才抓微笑曲线。我觉得这种工作方式和工作态度,你说我们要反思一下。
|
||||
- [00:39:17 - 00:39:23] 未知说话人08: 另外就是关于那个,就是客户的工作,中中国的时候我也跟那个。
|
||||
- [00:39:24 - 00:39:28] 未知说话人08: 财务部的领导做的够好,有几点。
|
||||
- [00:39:28 - 00:39:31] 未知说话人08: 也是同步市场部,也是给项目做一个做。
|
||||
- [00:39:32 - 00:39:35] 未知说话人08: 就是那个第1个,都是八零的两率。
|
||||
- [00:39:36 - 00:39:42] 未知说话人08: 就是到3月底,特别是3月底,就这个话,关键门儿说,市公司会有统一。
|
||||
- [00:39:44 - 00:39:48] 未知说话人08: 是不是会通用?所以说,就是它的满意的样板儿。
|
||||
- [00:39:48 - 00:39:58] 未知说话人08: 下来就是你跟那个小付一起,在我办公室我们讨论一下,满意客户满意的样板一定要按照四公司的规定来。
|
||||
- [00:39:58 - 00:40:01] 未知说话人08: 第2个是对于不满的客户。
|
||||
- [00:40:03 - 00:40:08] 未知说话人08: 它有两个时间节点,一个是五点半,一个是五点五点半过后。
|
||||
- [00:40:08 - 00:40:29] 未知说话人08: 还有五点半有几个操作的一个,有一个有个技巧。同时不满的客户要报警客户。因为现在不是这个指标不是KPK考核集团的,但是啊总是要求的,要考核分公司的。所以说这个事情,在操作上面是有空间的。
|
||||
- [00:40:32 - 00:40:35] 未知说话人08: 然后那个80200000000,我也看。
|
||||
- [00:40:36 - 00:40:41] 未知说话人08: 那还是不要,我们目前是属于一类的,到属于第2的左右。
|
||||
- [00:40:42 - 00:40:52] 未知说话人08: 也是不是低于全市的平均,所以说我觉得这个事情也是没有快速的把市公司的有一些技巧性的动作启动。
|
||||
- [00:40:58 - 00:41:02] 未知说话人08: 好,在考题上面都是八零两率,是有打印后面的。
|
||||
- [00:41:04 - 00:41:06] 未知说话人08: 这个是可以,是个是可以来平衡的。
|
||||
- [00:41:08 - 00:41:10] 未知说话人08: 好,这块儿的话,就是请那个。
|
||||
- [00:41:11 - 00:41:19] 未知说话人08: 商户,把每天的那个,就是每天,就是到月底之前,每天微信上面出个日报。
|
||||
- [00:41:21 - 00:41:23] 未知说话人08: 发送给发给我和小红嘛。
|
||||
- [00:41:25 - 00:41:28] 未知说话人08: 然后高关于考核,我也大概问了一下。
|
||||
- [00:41:29 - 00:41:32] 未知说话人08: 法律两界还是有那个,就是有可能有比较。
|
||||
- [00:41:33 - 00:41:39] 未知说话人08: 有可能又不高,也没说定。今年的KPAN考还基本上定了,是工信部的有责。
|
||||
- [00:41:40 - 00:41:53] 未知说话人08: 要考KPI啊,还有就是你的网率,就是跟满意度相关的,客户不走,就是按照那个观点,驾驶提升,就你的网率不高于去年,你应该是个,你应该是会拿个KPI来考核。
|
||||
- [00:41:57 - 00:41:59] 未知说话人09: 应该是一个,就是。
|
||||
- [00:42:00 - 00:42:04] 未知说话人09: 目前都是定了的,就是两个考核:一个是工信部有责,一个是。
|
||||
- [00:42:04 - 00:42:05] 未知说话人09: 都去。
|
||||
- [00:42:06 - 00:42:10] 未知说话人08: 8.2月是8.2月是有打印。
|
||||
- [00:42:11 - 00:42:23] 未知说话人08: 大概是这个样子,所以说把那个考核的情况你进一步再去摸细,还有那些都是可以可控的操作的一些动作。
|
||||
- [00:42:23 - 00:42:25] 未知说话人08: 跟子公司的话。
|
||||
- [00:42:27 - 00:42:32] 未知说话人08: 对吧?商务部都说的三个方面,商务部的话,我们最关注是把运动会、本周运动会。
|
||||
- [00:42:33 - 00:42:34] 未知说话人08: 对朱子豪。
|
||||
- [00:42:35 - 00:42:41] 未知说话人08: 我是星期跟下午到了,我要星期三、星期四出差,星期五到时候。
|
||||
- [00:42:43 - 00:42:51] 未知说话人08: 然后有啥事情,就是给我报告的事情。如果是来点计划,就明天,明儿下午,反正说几个事情。
|
||||
- [00:42:53 - 00:42:58] 未知说话人08: 给我汇报,如果来不及的话,都都用视频。好,星期五上午。
|
||||
- [00:43:06 - 00:43:07] 未知说话人10: 红火亮的樱桃。
|
||||
- [00:43:11 - 00:43:12] 未知说话人11: KPI。
|
||||
- [00:43:13 - 00:43:18] 未知说话人11: 刚才会上我们也过了1遍,按照我们定好的目标,确保完成。
|
||||
- [00:43:20 - 00:43:22] 未知说话人11: 好,马云的话。
|
||||
- [00:43:22 - 00:43:25] 未知说话人11: 具体的一些情况,请你们这个会后。
|
||||
- [00:43:27 - 00:43:28] 未知说话人11: 一个详细规划。
|
||||
- [00:43:29 - 00:43:30] 未知说话人11: 我想强调的是。
|
||||
- [00:43:32 - 00:43:32] 未知说话人11: 自信的。
|
||||
- [00:43:34 - 00:43:37] 未知说话人11: 我觉得,不管是部门儿还是。
|
||||
- [00:43:38 - 00:43:46] 未知说话人11: 不管是部门经理,还是主管,还是具体抓工作的人,和每一个一线的同志们,大家都要有那个执行力。
|
||||
- [00:43:47 - 00:43:50] 未知说话人11: 事情要办法,事不做好。
|
||||
- [00:43:52 - 00:43:54] 未知说话人11: 要知道怎么做,但是就是不去做。
|
||||
- [00:43:56 - 00:43:58] 未知说话人11: 那我觉得那是我们公司至少。
|
||||
- [00:43:59 - 00:44:03] 未知说话人11: 我们班子几个人是,我相信都不认可的那种工作风。
|
||||
- [00:44:10 - 00:44:12] 未知说话人11: 好,还有4公司的那个年度考核。
|
||||
- [00:44:13 - 00:44:18] 未知说话人11: 觉得几个部门主要是去了解情况啊,那个提前也给你们给说过几次。
|
||||
- [00:44:19 - 00:44:20] 未知说话人11: 如果有。
|
||||
- [00:44:21 - 00:44:24] 未知说话人11: 对我们影响比较大的一些病毒,或者是。
|
||||
- [00:44:25 - 00:44:33] 未知说话人11: 你要提前讲,不要等到起那个,别个都定好了再来跟我说,夏总,那个考核是今年子我们要照。
|
||||
- [00:44:34 - 00:44:35] 未知说话人11: 对,我说很。
|
||||
- [00:44:37 - 00:44:42] 未知说话人11: 我们把工作做在前面,你们细了解。我其实有点担心两个,一个是。
|
||||
- [00:44:43 - 00:44:45] 未知说话人11: 一个叫啥子啊?那个阿布咖啡。
|
||||
- [00:44:46 - 00:44:52] 未知说话人11: 那个全市,那个集团公司有一个啥子阿普提升,啥子考的,我不知道他怎么考,我不清楚。
|
||||
- [00:44:53 - 00:44:54] 未知说话人11: 很默契。
|
||||
- [00:44:55 - 00:44:57] 未知说话人11: 提升或者改善,或者啥,阿婆的啥子。
|
||||
- [00:44:58 - 00:45:01] 未知说话人11: 我觉得那个对,我我们公司,我不知道说不有。
|
||||
- [00:45:02 - 00:45:10] 未知说话人11: 我们要去,不管哪个样子,我觉得考核,我们其实我们不要求上市公司好像要对其他公司有啥子。
|
||||
- [00:45:10 - 00:45:17] 未知说话人11: 我要去想那些事情,但是至少是比较公平的。我们通过努力,我们可以去进行一个得乎点儿改善的。
|
||||
- [00:45:18 - 00:45:19] 未知说话人11: 最主要单位。
|
||||
- [00:45:20 - 00:45:22] 未知说话人11: 有提醒过,我我那边的话也会。
|
||||
- [00:45:24 - 00:45:28] 未知说话人11: 好,两个分管领导里面的话,也跟他们两个主要部门嘛,政企部跟。
|
||||
- [00:45:29 - 00:45:35] 未知说话人11: 他说:“我们加强力度嘛,然后如果确实有必要的话,我们可以去。”
|
||||
- [00:45:35 - 00:45:36] 未知说话人11: 也是。
|
||||
- [00:45:36 - 00:45:37] 未知说话人11: 好,那些沟通。
|
||||
- [00:45:39 - 00:45:50] 未知说话人11: 是一个年龄的一个非常重要的一点啊,不要开始我们处在起跑线上,那个很麻烦,不像我印象我们当时那个近视还在有1年,说我们那个啥子。
|
||||
- [00:45:50 - 00:45:52] 未知说话人11: 心也不靠海,是吧?
|
||||
- [00:45:53 - 00:45:58] 未知说话人11: 开始都是主要在细胞线上面,最开始为啥子不够通行?有那种卡位口结和那些。
|
||||
- [00:45:59 - 00:46:08] 未知说话人11: 是吧?我也相信,市公司他也应该会考虑分公司的整体情况,然后统筹来,至少大家都能够调高摸得度,是吧?
|
||||
- [00:46:14 - 00:46:16] 未知说话人11: 今天的周会就到这儿结束。
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"sub_topics": [
|
||||
{
|
||||
"title": "宽带装维上门进度与质量指标通报",
|
||||
"time_interval": "00:00:01 - 00:02:06",
|
||||
"overview": "会议回顾宽带装维上门量与安装进度的平衡情况,当前累计上门量超1000户,距3000户目标进度偏后,周均上门量约1000次,月均约4000次。关键质量指标方面,弱光率当前为0.51即将达到0.5目标,三类终端指标较上周下降0.1个百分点,FTDR已达标,但主动跟进指标相对靠后。"
|
||||
},
|
||||
{
|
||||
"title": "九零工程转化率与退单率分析",
|
||||
"time_interval": "00:02:07 - 00:03:51",
|
||||
"overview": "汇报“九零工程”月度转化率87.35%(目标90%)及退单率6.53%(目标低于7.5%),退单主因包括改约、用户原因29单及天气影响2单。针对蓝单转化率仅75.29%及退单率偏高问题,提出将退单率纳入综合运维考核,并建议剔除分局长审批同意的退单以优化考核公平性。"
|
||||
},
|
||||
{
|
||||
"title": "专线质量恶化与PCDN治理探讨",
|
||||
"time_interval": "00:03:53 - 00:05:31",
|
||||
"overview": "专线指标持续恶化,主要问题集中在人文与海师两所学校,已报市公司分析出口IP地址。会议探讨了建立后台自动限速机制的可行性,明确学校互联网带宽虽免费但需规范使用,后续发现问题将第一时间通过系统上线处理并协同全资方落实管控。"
|
||||
},
|
||||
{
|
||||
"title": "网络质量专项攻坚与故障处理通报",
|
||||
"time_interval": "00:05:33 - 00:08:04",
|
||||
"overview": "通报三创空间天线缺货延至4月初检测,畅听工单需智能体逐项核查,5G弱化问题正试点调整基站参数。超频站点攻坚发现3处故障(铁塔开关电源及传输光衰)均已恢复,专线护航118条中已巡检56条,剩余17条月底完成。当周共收故障33件,9件网络相关以光缆问题为主。"
|
||||
},
|
||||
{
|
||||
"title": "二级基站清理与工程下沉推进",
|
||||
"time_interval": "00:08:07 - 00:09:35",
|
||||
"overview": "二级基站清理工作进展顺利,2026年剩余121站已全部下电,累计拆除46站,预计两周内完成剩余75站拆除及资费调整,确保4月15日前全量完成。工程下沉项目正常开展,已接收网络质量综合评估体系,下周将针对该体系进行指标分解与目标制定。"
|
||||
},
|
||||
{
|
||||
"title": "综合部行政后勤与工会活动筹备",
|
||||
"time_interval": "00:09:46 - 00:12:39",
|
||||
"overview": "综合部汇报无人机验收待推动、招投标打印机外协洽谈(内外价差超十倍)及气象/渠道/专线发展计划。工会经费压降背景下,推进食堂改造(预算29.8万元)及直升机引水项目获批。筹备第四届体育文化节,确定“河川佳绩,穿越巅峰”主题,正协调各部门补充方阵人员并安排周二至周四排练。"
|
||||
},
|
||||
{
|
||||
"title": "招待费管控与区级评优申报研判",
|
||||
"time_interval": "00:12:40 - 00:27:30",
|
||||
"overview": "通报2025年招待费超年初预算14%,综合部2024年曾超支107%,2026年仅综合部调整预算,要求统筹正气部对外招待并加快报销结算。针对河川区“担当作为”评优申报,因往届多为政府机构且评选流程未明,领导指示需提前摸底决策领导意向后再决定是否投入精力,避免形式主义消耗。"
|
||||
},
|
||||
{
|
||||
"title": "商客市场拓展与“查企”数据复盘",
|
||||
"time_interval": "00:27:32 - 00:34:04",
|
||||
"overview": "“查企”工作累计完成690万收入与1110户发展,主要采取低ARPU价值提升与融合套餐策略,本周开展5场社区/单位营销但龙狮业务转化不佳。商客市场1月收入88.5万元(同比增1万),价值拓展排名全市第6,个别分局增幅超2万,但部分经理周基础业务仅2笔,进度滞后需加强。"
|
||||
},
|
||||
{
|
||||
"title": "工作作风整顿与满意度考核部署",
|
||||
"time_interval": "00:34:04 - 00:42:32",
|
||||
"overview": "领导严厉批评部分工作回复滞后、缺乏量化措施,要求养成“日事日清”习惯并今日提交专线与商客指标保障方案。市场部满意度测评垫底,指出正气部负责人缺席客户会导致工作松懈,要求本周内汇报招聘、农村渠道及行销转型进度。明确今年KPI考核将纳入工信部有责与离网率,要求吃透市公司技巧确保3月底“八零两绿”达标。"
|
||||
},
|
||||
{
|
||||
"title": "年度考核指标预沟通与会议总结",
|
||||
"time_interval": "00:42:33 - 00:46:16",
|
||||
"overview": "会议最后强调全员需强化执行力,杜绝“知而不做”的作风,要求各部门提前与市公司对接年度考核口径与潜在指标(如APP提升考核),避免起跑线落后。领导指出考核争取公平得分需靠主动沟通与前期铺垫,各部门需联动协同,周会至此结束。"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"sub_topics": [
|
||||
{
|
||||
"title": "宽带安装维护与核心运营指标通报",
|
||||
"time_interval": "00:00:01 - 00:03:51",
|
||||
"overview": "会议通报了宽带安装与上门服务的进度,受天气影响上周上门量达580,累计进度滞后于3000户目标。重点分析了弱光(0.51)、三代终端(年度目标5.5)、转化率(87.35%)及退单率(6.53%)等关键指标,指出退单主要受用户原因、覆盖不足及天气影响。会议建议将阶段性目标纳入运维考核,并优化审核流程以降低退单率。"
|
||||
},
|
||||
{
|
||||
"title": "专线护航、网络质量优化与基站攻坚进展",
|
||||
"time_interval": "00:03:53 - 00:08:04",
|
||||
"overview": "针对PCDN专线恶化问题,已上报市公司分析学校出口IP并协同限速,同时推进5G基站参数调整试点以解决漏话问题。专线护航方面,118条专线中存量73条已完成56条巡检,剩余17条确保月底全量完成;上周共收报障33件,其中9件为网络相关(主要为光缆问题)。超频基站攻坚发现3处故障,已分别通过修复铁塔开关电源和更换传输光纤恢复。"
|
||||
},
|
||||
{
|
||||
"title": "二级站点拆除计划与网络评估体系分解",
|
||||
"time_interval": "00:08:07 - 00:09:35",
|
||||
"overview": "金沙管家二级站点拆除工作推进顺利,剩余75站预计于4月15日前完成全量拆除、下电及电费调整。工程下层项目整体正常开展,综合网络运维评估体系已内部收悉,计划下周进行指标分解与目标制定。东环网络质量保持良好水平,并在全市范围内进行了经验交流。"
|
||||
},
|
||||
{
|
||||
"title": "综合部专项工作推进与后勤设施改造",
|
||||
"time_interval": "00:09:46 - 00:12:39",
|
||||
"overview": "综合部汇报了25年剩余2项重点工作的推进情况,上周已完成建委框架清单整理、投资计划评估及收入地图提交等5项工作。后勤方面,因内部打印机报价偏差过大,正洽谈外部打印店以保障招投标需求;同时推进食堂改造(预算约29.8万)及下半年引入自饮机以节约成本。工会经费面临压减,需以更优方式落实软性工程改造。"
|
||||
},
|
||||
{
|
||||
"title": "年度工会活动规划与第四届体育文化节筹备",
|
||||
"time_interval": "00:12:40 - 00:18:54",
|
||||
"overview": "会议规划了全年六场大型体育活动,并重点部署了5月底举办的第四届体育文化节,主题为“河川佳节,穿越巅峰”。因两名主力选手肌肉拉伤无法参赛,现需各部门协调补充人员,计划从一线生产部门及AI运输中心抽调共计9人组成25人方阵。参会人员将获得绩效加分,需于今日确定名单以便统一采购服装并开展排练。"
|
||||
},
|
||||
{
|
||||
"title": "主题教育落实、招待费管控与区级评优申报",
|
||||
"time_interval": "00:18:55 - 00:26:52",
|
||||
"overview": "主题教育首期简报已发布,基层党组织学习工作已按期完成;2025年招待费超年初预算14%,其中综合部历史超支明显,2026年已调整预算并强调对外招待需统筹分配。会议讨论了申报“河川区担当作为先进集体/个人”的可行性,指出该评选竞争激烈且需推荐,建议提前核实资格避免资源浪费。"
|
||||
},
|
||||
{
|
||||
"title": "商客市场经营分析与二期项目拆迁进展",
|
||||
"time_interval": "00:26:55 - 00:32:04",
|
||||
"overview": "商客市场2月收入达88.5万元,环比增长1万元,城北和南溪改增幅超2万元,但价值拓展仅完成115,两名商客经理基础业务量偏低。二期项目拆迁方面,已完成1145户,重点通过二次融合套餐将低价值合约提升至50元档位;本周开展5场社区及单位营销,但签约转化未达预期,需加强后续落实。"
|
||||
},
|
||||
{
|
||||
"title": "工作执行力整顿与满意度/KPI考核部署",
|
||||
"time_interval": "00:32:05 - 00:46:16",
|
||||
"overview": "领导严厉批评部分工作拖延及缺乏具体保障措施的现象,要求养成“日清日结”习惯并量化汇报结果。针对满意度测评,指出政企部前期工作松懈导致指标落后,要求市场部立即制定挽单方案并按市公司规范执行。会议明确今年KPI将挂钩工信部有责投诉及离网率,要求各部门提前摸排考核风险,强化执行力以确保年度考核达标。"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
|
||||
# 会议记录
|
||||
|
||||
议 题:合川分公司周例会(2026年第X期)
|
||||
|
||||
时 间:2026年5月8日 10:38—10:50
|
||||
|
||||
地 点:分公司会议室
|
||||
|
||||
主持人:管理员
|
||||
|
||||
参加人:分公司领导、各部门经理及AI云数中心经理
|
||||
|
||||
议程:
|
||||
|
||||
一、各部门汇报
|
||||
|
||||
二、分公司领导指示部署
|
||||
|
||||
---
|
||||
|
||||
## 会议内容
|
||||
|
||||
### 一、各部门汇报
|
||||
|
||||
建维部、综合部、市场部及政企部按议程依次汇报。建维部通报宽带装维进度:当前累计上门量突破1000户,距3000户目标进度偏后,周均上门约1000次;弱光率0.51逼近0.5目标,三类终端指标改善0.1个百分点,FTDR达标但主动跟进指标靠后(0.3)。“九零工程”月度转化率87.35%(目标90%),退单率6.53%(目标<7.5%),退单主因改约及用户原因;蓝单转化率75.29%,建议将退单率纳入运维考核并优化考核口径。专线质量受两所学校IP地址影响持续恶化,已报市公司分析并探讨后台自动限速机制;三创空间天线缺货延至4月初检测,5G弱化问题试点调整基站参数;超频基站3处故障已恢复,专线护航118条中56条已巡检,剩余17条月底完成。综合部汇报无人机验收待推动、招投标打印机外协洽谈(内外价差超十倍)、食堂改造(预算29.8万元)及直升机引水项目获批;第四届体育文化节正协调各部门补充8名方阵人员,周二至周四排练。市场部通报“查企”累计完成690万收入与1110户发展,商客市场1月收入88.5万元(同比增1万),价值拓展全市第6,但部分经理周基础业务仅2笔进度滞后。
|
||||
|
||||
---
|
||||
|
||||
### 二、部署强调
|
||||
|
||||
#### 建维部负责人强调:
|
||||
|
||||
1. **装维与质量指标方面:**
|
||||
- 兼顾安装与上门量,加快追赶3000户目标进度
|
||||
- 保持弱光率与三类终端改善势头,专项提升主动跟进指标
|
||||
- 建议将退单率纳入综合运维考核,推动剔除分局长已审批同意的退单以保公平
|
||||
2. **工程与网络攻坚方面:**
|
||||
- 2周内完成二级基站剩余75站拆除,确保4月15日前全量完成下电与资费调整
|
||||
- 按期完成专线护航剩余17条巡检,存量光缆路由抢盘行动及时上报
|
||||
- 下周内分解网络质量综合评估体系指标并制定阶段性目标
|
||||
3. **故障处理与专项测试方面:**
|
||||
- 持续压降超频站点及旁站故障,当周33件故障以光缆问题为主需重点排查
|
||||
- 跟进三创空间天线检测及5G弱化基站参数试点调整效果
|
||||
- 协同全资方建立专线自动限速机制,规范学校带宽使用并第一时间系统上线管控
|
||||
|
||||
---
|
||||
|
||||
#### 分公司领导强调:
|
||||
|
||||
1. **市场与政企拓展方面:**
|
||||
- 深度复盘商客市场与“查企”数据,加强低ARPU价值提升与龙狮业务转化
|
||||
- 严抓部分经理周基础业务仅2笔的滞后问题,以周为单位严格跟踪并加快分局推进节奏
|
||||
- 扭转满意度测评垫底局面,政企部负责人须亲自抓客户会工作,杜绝思想松懈
|
||||
2. **行政后勤与费用管控方面:**
|
||||
- 统筹政企部对外招待,加快报销结算,严控招待费超支风险(25年已超预算14%)
|
||||
- 摸底区级“担当作为”评优申报决策领导意向,避免形式主义消耗
|
||||
- 落实招投标打印机外协保障方案,确保不影响招投标业务开展
|
||||
3. **作风建设与考核部署方面:**
|
||||
- 严厉批评工作回复滞后、缺乏量化措施,要求全员养成“日事日清、日结日高”习惯,今日提交专线与商客指标具体保障方案
|
||||
- 市场部需本周内汇报招聘进度、农村渠道建设及行销队伍转型方案
|
||||
- 吃透市公司考核技巧,确保3月底“八零两绿”达标,今年KPI将纳入工信部有责与离网率
|
||||
- 强化全员执行力,严禁“知而不做”作风,各部门需提前对接市公司年度考核口径(如APP提升考核),主动沟通争取公平得分,避免起跑线落后
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
|
||||
# 会议记录
|
||||
|
||||
议 题:合川分公司周例会(2026年第19期)
|
||||
|
||||
时 间:2026年5月6日13:37—14:23
|
||||
|
||||
地 点:分公司会议室
|
||||
|
||||
主持人:AlanPaine
|
||||
|
||||
参加人:分公司领导、各部门经理及相关人员
|
||||
|
||||
议程:
|
||||
|
||||
一、各部门汇报
|
||||
|
||||
二、分公司领导指示部署
|
||||
|
||||
---
|
||||
|
||||
## 会议内容
|
||||
|
||||
### 一、市场部、政企部、建维部、综合部︱党群纪检部按议程现场按顺序做汇报。综合部按照领导部署通报周例会领导部署工作推进完成情况:2026年重点工作跟踪本周完结5项(综合部牵头完成5项),待跟进20项,详见汇报材料。
|
||||
|
||||
**建维部与网络质量管控:**
|
||||
- **宽带与上门量:** 受天气影响上周上门量580户,累计进度距3000户目标略靠后;弱光值改善至0.51(逼近0.5目标),三代终端压降至5.5,FPTR达标,主动过境率0.3需提升。
|
||||
- **九零工程转化与退单:** 月度转化率87.35%(目标90%),退单率6.53%,主因用户原因(29单)及天气。需优化B2C协调流程,建议引入一线审批提单机制。
|
||||
- **PCDN专线与基站维护:** 专线指标恶化集中于两所学校,已上报市公司分析出口IP,拟建立快速发现与限速机制。超频基站3个已查明原因并恢复。专线护航118条,月底完成全量巡检。当周报障33件(网络相关9件,主要为光缆)。金沙管家二级站点剩余75站,2周内拆除下电,4月15日前完成服务费调整。
|
||||
|
||||
**综合部与行政后勤:**
|
||||
- **项目推进与后勤:** 25项剩余工作已完成5项(含施工司管清单、投资计划评估等)。解决打印机价格偏差问题,对接外部保障招投标打印。工会经费压减,食堂改造约29.8万元待审计。
|
||||
- **招待费通报:** 2025年整体招待费超年初预算14%,综合部去年超支107%已调整2026年预算。
|
||||
- **区级评选申报:** 区委办与人社局联合开展担当作为集体/个人评选,需确认申报资格与内部推荐名额,建议先与委办及人社局经办领导沟通,避免盲目申报。
|
||||
|
||||
**市场部与政企部:**
|
||||
- **拆迁与商客市场:** 三期拆迁已完成1145户,通过二次扩容提升低价值用户转化。商客2月收入88.5万元(环比增1万),价值拓展完成115,但个别经理基础业务薄弱需督导。
|
||||
- **满意度与考核准备:** 满意度测评近期为拉分项,负责人需亲自抓。KPI考核将挂钩工信部有责及离网率,需每日跟进并制定管控动作。
|
||||
|
||||
---
|
||||
|
||||
### 二、分公司领导指示部署
|
||||
|
||||
#### 会议领导强调:
|
||||
|
||||
1. **作风建设与执行力:**
|
||||
- 严抓工作拖延现象,全员须养成“日清日结”习惯,工作回复必须量化、有结果、有措施、有成效。
|
||||
- 杜绝“有方法无动作”的作风,部门经理及一线人员需强化执行力,事项不落实不罢休。
|
||||
|
||||
2. **业务指标整改与保障:**
|
||||
- 上课指标与专线助账客业务责任人须于当日提交具体可行的保障方案,结合专线助账客单位发展确保指标达成。
|
||||
- 3月底为满意度测评关键节点,须严格按市公司规定打造样板。针对不满客户需利用5:30等时间节点技巧管控。KPI明确挂钩工信部有责及离网率,市场部需每日微信日报跟进。
|
||||
|
||||
3. **预算统筹与年度考核预警:**
|
||||
- 政企部须统筹对外招待安排,避免费用过度集中于个别客户经理,真实发生费用需及时结算报销。
|
||||
- 各部门需提前细查四公司年度考核指标,对可能产生重大影响的考核偏差或风险点必须提前预警上报。政企部与市场部需加强沟通力度,必要时向上协调,确保考核公平合理,避免起跑线吃亏。
|
||||
|
|
@ -0,0 +1,777 @@
|
|||
未知说话人01
|
||||
00:01
|
||||
也是我们也对宽带的重视,也是有一定的效果哈。
|
||||
未知说话人01
|
||||
00:06
|
||||
然后上门处理,因为上周第1个是下雨的原因,第2个导致的安装的上门的量的下降,所以当周的那个上门量还是比较高五百八十哈。所以说那个累计上门量达到了以前以上哈,但是离离我们的目标三千户的话这1块,稍微进度还是靠后哈,主要还是因为上门这块和那个,和安装这安装这块的平衡哈,要两边都要兼顾。总体的话,线路故障的话这1块是比较平稳哈。
|
||||
未知说话人01
|
||||
00:37
|
||||
你那个说法,刚刚说的本来那个安装没得好多量的噻。不是没得量,下雨。
|
||||
未知说话人01
|
||||
00:43
|
||||
下雨打的,上周下雨。上面都应该黑皮的啊。上面就比较好的,咱们这上面比较好的。那整个加在一起的话,你才。前面前面我们不是。累积了35的进度,那个进度不高哦。前面2周不是安装达到了一千吧,最近。
|
||||
未知说话人01
|
||||
00:58
|
||||
你给我看后面,我们这上周我们安装只有接近400。
|
||||
未知说话人01
|
||||
01:02
|
||||
所以说这个安装量和上门量,它2个还是就是每1周还是达到了将近1000的上门量,就是安装和维护的上门还是有1000,然后每个月的四达到了4000的上门量,然后再看一下那个。
|
||||
未知说话人01
|
||||
01:17
|
||||
这个刚刚说的就是那个上门整个指标的情况的话,就是从上门之后的指标几个关键指标,第1个是弱光,弱光现在目前是0.51,也是在上周持续在向好,即将达到零点五的那个目标。三代终端也是因为全年因为去年的目标是七点五,今年要求的年度目标是五点五,所以说这个需要1个持续往下压的过程,这个也是较上周提升了0.1个百分点,就是下降了哈,就是有有改善。所以说这个是年度目标的话,我也跟司空建议了,这个指标它会拉入到运维,我也建议他们那个每1个季度设1个阶段性的目标,不然的话全市的话五点五都达不到现在目前。FPTR现在是达标了,就上周这块,那达标哈,主动过境这块是靠后,零点三,这是1个上门之后的效果。
|
||||
未知说话人01
|
||||
02:07
|
||||
然后那个九零工程转化率要达到90%,退单率要低于七点五。然后整个月度来看的话,我们现在是转化率是87.35,离90的目标还差一点点。但是当周来看的话,主要是天气影响啊。当周的虽然上了80%哈,但是离90的目标还是差的很远。但是月度来看的话,都是转化率还是有很大的提升哈,接近90,退单率是6.53。整个退单的那个改约的情况是影响那个转化率的1个主要因素,主要是用户原因二十九单,覆盖六单,天气两单。
|
||||
未知说话人01
|
||||
02:41
|
||||
整个退单来看的话,主要是用户不安装退单十六单卡,长期无法连续三单。
|
||||
未知说话人01
|
||||
02:48
|
||||
还有入错四单,低价值入错建设,用户入网不通哈,这块。3块蓝单的话,就是上周的话,那个没达到80%哈,56.82,整体的当月的转化率是75.29,也是比八十还是稍微还差一点的哈,退单率是44.29。
|
||||
未知说话人01
|
||||
03:07
|
||||
然后退单率比较高的原因,主要还是那个B to C的这1块的那个协调问题。这块1个是审核,撤单的退单的流程审核已经给施工是那个建议了。当时那个院里经理也专门跟我打电话哈,他也是明白了我们想做的那个这个这个这个审核的1个流程意识,他们也在正在开发。然后同时的话,也那个这个指标也会也会是我们综合运维的1个考核指标。我们也建议了施工是上次来也建议他们这个退单率应该看能不能提出这种分居长,如果这种一线审批如果同意了,我觉得还是应该提出的啊。不然的话,这种团单来了之后啊,都是都是都是他自己有一些个人的意识在里面,要退单啊。
|
||||
未知说话人01
|
||||
03:53
|
||||
PCDN那个专线持续在恶化,然后主要还是学校,就是当当月3月份的话是开学之后啊是4.84,这个的话1个就是我们把那个涉及到的IP地址已经报市公司帮我们分析这个出口的学校的IP地址,因为目前数据我们上周跟他们沟通之后他们现在这1周才能反馈那个,啊是集中在1个学校吗?2个学校,人文和是海南还是还是,就2个学校。
|
||||
未知说话人01
|
||||
04:22
|
||||
我但这个我报全职以后,他是不是马上就会过限速啊?呃,他是要把IP地址分析出来之后,要报给学校限速。学校他们现他们现在也在协同他们。啊。我们。我们也在找全职,他们能不能帮我们后来限建立这种机制?因为三关,因为加关和启关现在都已经都施工都不通报了,周报也没有了,主要是现在主要问题还是在专线。问问题是专线主要还是在学校我们。学校的话,因为我们只是提供他的出口带宽,他的IP地址啊那些数据的话,要经过那个。而且学校的话互联网带宽我们是没收费的。对免费。这个是更不应该出现问题了。哎,这个他们这个学校这边的话,如果有问题,我觉得第1时间就应该直接就在系统上限。对,我们也在想这个是正常的这个行为。我们也也想在那个。学生在沟通一下嘛。一旦发现直接限掉,他也没什么好说的。他作为1个学校,或者是那个什么,他那个提供的是正常的那个带宽使用的这个速度。如果他那个这个超过了这个的话,那这这这是有问题啊。嗯。我现在在学校全职,尽快的话看有没有
|
||||
未知说话人01
|
||||
05:33
|
||||
啊这是这是整个那个P C N啊,3次空间主要1项没达标,主要就是那个物业点那个本月那个。
|
||||
未知说话人01
|
||||
05:42
|
||||
那个之前是计划的本月,但是反馈天线还现在没有过,预计4月初进行1个检测轨道。
|
||||
未知说话人01
|
||||
05:50
|
||||
其他的都是达标的。
|
||||
未知说话人01
|
||||
05:53
|
||||
然后唱厅有1项,主要是那个,其实问题都解决了,但就是要带智能体,要智能判断,剩余工单要逐项的核查是否达标才能算结束。所以说虽然是处理了,但是要等到质检,其他指标都是达标的。然后还有1个有12项自行工作啊,智能添加的,就是也包括南中也的反馈,就是我们有些打接电话没有接到哈。然后他们也是,当周的现在目前的解决方案是,爱立信5G基站参数的调整试点,带观察效果哈,这个近期反映的就是有漏话,这种情况比较多,5G这1块。
|
||||
未知说话人01
|
||||
06:32
|
||||
然后那个畅想这块全部达标哈,就结束了。然后,那个超频站点的攻坚这块是是控制还是比较那个,有帮助哈。就是上周我们发现了3个超频基站,呃有2个原因是铁塔的开关电源故障导致电流过稳,所以说也及时的处理,就进行了1个恢复。然后还有1个就是传输光纤过大哈,这个维护部人员更换前厅后恢复,这个也是说把它解决了。然后旁站的故障的话也持续在也是处理也比较低。
|
||||
未知说话人01
|
||||
07:03
|
||||
然后专线护航目前来讲的话,118条专线我们目前的话有存量的73条的话,已经完成巡检56条,还有17条。然后未验收的工程已经建设的有45条全部进行了巡检。然后四公司要求是3月底全量完成巡检,目前17条的话,我们在月底能够按时进行1个全部巡检来完成。然后主要是那个涉及到存量这1块,我们立即力改都改了,主要还是涉及到光光缆路由的这块有抢台行动,我们会及时的上报给四公司。然后上周的话我跟机科里面的培训,客服出了问题主要还是他们内部的那个,就是他们的机房和机柜这块的问题比较比较严重哈,这块也是。今天我们会就是这1周的话这2天会把全量的清单,我们的问题客服处理的问题全量的发给客服经理,让他们知晓并与客户沟通。
|
||||
未知说话人01
|
||||
07:57
|
||||
然后当周故障的话是收到报障是33件,然后9件跟网络相关,主要问题还是光缆这块的问题啊。
|
||||
未知说话人01
|
||||
08:07
|
||||
然后东环呢也持续保持1个良好的1个水平,上周还在全市做了1个那个交流。
|
||||
未知说话人01
|
||||
08:14
|
||||
啊,金沙管家这1块重点,那个说一下二级,因为上周小总也安排了二级。二级的话,整个我们目前哈,就最新的数据,我们现在剩下20206年总共还剩下一百二十一站,这二百一百二十一站其实上周也是抓紧处理,已经全部下电了。然后目前累计完成拆除是四十六站,还有75站。七十五站预计的话,我们争取的话是在2周之内完成全量的拆除,然后进行只管专署以及电量服务费4月的1个调整。也就相当于在4月15号之前可以全量完成二级的拆除和下电和服务费的调整。
|
||||
未知说话人01
|
||||
08:55
|
||||
好,工程下层项目都很正常哈,除了那个他们那个,那个单子也也在补当中哈。
|
||||
未知说话人01
|
||||
09:06
|
||||
然后其他的就是也都是正常开展的。
|
||||
未知说话人01
|
||||
09:09
|
||||
其他就是没有啥子大的问题啊。
|
||||
未知说话人01
|
||||
09:12
|
||||
还有就是最后1个就是网络质量综合评估体系哈,虽然没有发文,但是已经已经给已经发下来了。那个我们内部先收到了,这1块我们会,嗯后面就是下1周的话我们会针对综合网网络运维评估体系进行进行1个那个进行1个分解和目标的1个制定啊,这边就没有起来了。
|
||||
未知说话人02
|
||||
09:46
|
||||
呃,25年剩余2项工作哈,呃,第1个花果山那个没得啥子变化的,第2个微托无人机哈,是说的在金南人组织验收以后,是花本周哈拜访唐书记进行推动,啊,是项目组的1个。
|
||||
未知说话人02
|
||||
10:01
|
||||
嗯上周完成了5项工作哈,包括嗯这种要求,建委哈对施工司管的框架下整理的工作清单哈,以及投资计划专项评估汇报哈,建委部答复是已经汇报,并且完成。然后市场那块终端占比问题哈,嗯是进行了1个全方位工工的1个重点的1个汇报哈,形成了1个5个方面哈制定了具体的措施哈,嗯解决问题,最终又提升啊,答复是已经进行了专题研讨汇报。嗯,正中安排的收入地图和行业中心的收入地图哈,是各中心已经完成,并且经嗯要求进行了提交,啊,中核集团。嗯,打印机哈那块是跟局科到现场办公室沟通以后哈,现在已经是收回中国国,啊专门为我们嘞调度表哈预留1.1元个打印机哈。同时啊那块我们也在思考哈如何确保哈,了解了他们日常需求的嗯打印数量哈,嗯打印情况以后哈,嗯我们在周边的哈打印店也进行了一些洽谈。
|
||||
未知说话人02
|
||||
11:04
|
||||
嗯,最终他们的价格偏差还是很大,有十倍以上。啊,最后我们嗯跟建,跟那个叫啥,整整套是吧?啊,整套。啊,整套。沟通以后,到时候我们去试,他有需求的时候,我们陪到一起去试,哈,确保质量的情况下,哈,我们呃提供1个相当于外派点,哈,进行1个保障,哈,确保那个招投标的打印,嗯,不影响招投标。嗯。
|
||||
未知说话人02
|
||||
11:28
|
||||
然后,那个气象。
|
||||
未知说话人03
|
||||
11:30
|
||||
那个事情给那个行业中心和那个,哎,运输中心都说,都是个人自己要晓得哦,下回不要再给我,再给我以那个理由,再说去答应你有问题哈,那都是个人的问题。
|
||||
未知说话人03
|
||||
11:43
|
||||
请你们通知到位,好吧。
|
||||
未知说话人02
|
||||
11:48
|
||||
然后有7项工作人,在推动过程中。第1个是前期交办的预期数据中心哈整体包包装哈,那块儿是说政府要拿出方案,补贴方案以后的话,嗯,再汇报。嗯,无人机哈那个需求哈,结合到落实成为合川本地的1个方案,目前没得啥子变化和之前的反馈。嗯,然后基建工程2个宣传工作计划,中国那边在推动基建工程2个是是嗯,留言后哈,目前还没下发下发以后,我们在优化制定。啊,宣传工作那块儿目前说之后哈,争取本周完成1个,那个嗯推动啊,因为工作人兼职的原因啊。然后那个嗯渠道那块儿呢,有1个产能评估哈,那块儿是计划,嗯开了宣传会哈,嗯还在梳理方案,最后是结果情况,预计在本周进行1个专题汇报。嗯,专线发展节奏的问题哈,希望整体思考,整体将。
|
||||
未知说话人02
|
||||
12:40
|
||||
那个数据进行了展示哈,然后嗯体现的是整体情况,本周专题汇报。嗯,然后分局是那个资产优化的运输类的话,是形成了那个清单周报。嗯,然后那个每周与分局进行沟通,形成1个清单的1个呃计划,啊具体的优化方案,嗯完成以后哈进行1个完结,啊,那是在跟进的效果。呃,综合当前几点有1条有些做的工作哈,请大家知晓。呃,3月20号我们也召开了分公司的话,呃工会主席面对面哈进行了一些沟通,1个是我们的工会经费进行1个公示。啊,因为整个工会经费哈从市工会到市公司哈再到分公司都有所压减,啊所以今年我们需要一记严考用更少的钱哈办更好的事儿哈。然后主席给我们做了一些具体指引哈,大家有啊积极发言。同时今年我们在本周需要上报市公司的软性工程哈,嗯其中我们已经确定的啊可以上报哈目前沟通的哈,包括我们更衣室哈包括我们食堂的改造。食堂改造那边的话,嗯按照之前的方案是大概是二十九点八万哈,然后我们将会进行1个审计。呃结合到大家用餐的时间哈,我们提出的建议是5月哈结合
|
||||
未知说话人02
|
||||
14:54
|
||||
更替和修补。呃,同时呃,市公司呃呃,和分公司哈,我们做了解以后哈,也是收集大家意见以后,包括啊,我们准备呃引用那个自饮机的方式哈来解决我们用水的问题哈,呃,送水啊那些呃机器也坏了,啊,自饮机那块儿的话也报了市公司哈,对批准,啊,等到去批复以后啊,我们就可以引入,大概在下半年的时候哈,啊,我们就可以用自饮机哈进行饮水,同时也节约成本。
|
||||
未知说话人02
|
||||
15:21
|
||||
嗯,幸福一家一的活动哈,全年同时组织了六场啊大型活动啊,包括3月的运动会啊,4月的足球,5月的羽毛球,6月的篮球,10月的气排球和10月的乒乓球。啊,分公司对于除了参加四公司活动以外哈,整体还安排的有一些重大节假日的一些活动,包括近期我们啊在思考筹备的6月二中节啊的1个活动,以及我们那个啊班组活动哈,班组活动那边的话也是整整出了大家的意见哈,可能今年我们也在思考是不是搞1个我们分公司内部的班组之间的啊嗯气排球比赛啊,通过那种形式哈来解决那个啊班组各自开展活动哈那种另行开展的那个方式哈,然后根据的一些啊就是在1个思考过程中。嗯同时重点汇报一下周五哈计划的是第4届体育嗯文化节,啊我们河川将以河川佳节哈穿越巅峰,一起新嗯一起新城,然后动要赛场哈1个主题口号,结合到我们泡竹汤哈啊出名的1个形式,通过我们方正和演员的演出哈,将我们啊深情的河川河川的那种啊快乐啊热情的那种精神面貌哈展示给全市的啊兄弟公司和领导
|
||||
未知说话人02
|
||||
17:08
|
||||
啊,原来黄翔啊,他们都是因为啊有伤在身啊,无法参加。啊,他们觉着不行啊。啊,他不得行。
|
||||
未知说话人02
|
||||
17:17
|
||||
这是哪儿受伤了啊?呃,他肌肉拉伤。
|
||||
未知说话人02
|
||||
17:23
|
||||
呃,没法成交吗?哎,对,他不敢跑,对吧?
|
||||
未知说话人02
|
||||
17:27
|
||||
方向啥情况啊?呃也是。
|
||||
未知说话人03
|
||||
17:31
|
||||
2个2个主力选手都不得行哦,那那个今年是那个有点儿具体哦,平时主持体格。
|
||||
未知说话人02
|
||||
17:38
|
||||
呃,他是那么跟我说的。
|
||||
未知说话人03
|
||||
17:41
|
||||
我29,然后他们七八。
|
||||
未知说话人03
|
||||
17:44
|
||||
看得起啊,我说没看得起黑老婆呀。
|
||||
未知说话人02
|
||||
17:48
|
||||
啊,他不敢不敢爆发爆发性的发力,那种。如果是,如果是确实受伤了,我觉得吧,就不能勉强,因为我。
|
||||
未知说话人02
|
||||
17:58
|
||||
好,然后完了以后的话,就是需要各部门儿积极配合,特此请示领导。1个就是我们方阵哈,目前除了我们参赛的队员儿和我们,呃和本人哈作为方阵队员儿以外哈,可能我们容纳到20个人来进行那个活动开展。嗯,再加上领导和1个举牌手和1个那个形象,嗯大师以外,我们一共需要25人。好,我们确定的呃报名人数以外的话,我们还差9个人,还差9个人的话看,呃结合到那个一线生产工作嘞繁忙哈,嗯那个过度,嗯看是不是各部门儿再出2个人哈。啊,构成我们8人的方阵哈另外AI运输中心出1个人哈,我们总共目前差9个人。啊,确定人员的话需要今天确定,确定以后我们需要给他们购买衣服。啊,购买衣服以后周二到周四进行排练,啊就是下班以后,然后星期五都去参加活动。好,那块儿的话看领导觉得合适那种分配。
|
||||
未知说话人02
|
||||
18:55
|
||||
1个男生整起来。
|
||||
未知说话人03
|
||||
19:00
|
||||
电脑都没地方,每个部门2个人该出出来,是这个想法。
|
||||
未知说话人02
|
||||
19:05
|
||||
嗯,周二到周四要拍的呀。
|
||||
未知说话人02
|
||||
19:07
|
||||
买了几件参加哈。
|
||||
未知说话人03
|
||||
19:10
|
||||
不是,确实跟到2个人都看不出来,跟我说。
|
||||
未知说话人02
|
||||
19:15
|
||||
性别性呢?呃,不行。
|
||||
未知说话人03
|
||||
19:19
|
||||
大家说清楚有衣服的。
|
||||
未知说话人02
|
||||
19:23
|
||||
啊,同时呢,参加以后,介会我还上决赛哈,嗯,和往年一样,积极参加的还是有一定的绩效的,1个加分儿,只要参加,方阵的是每人一分儿,啊,获获得名次的啊更多一些。
|
||||
未知说话人02
|
||||
19:36
|
||||
好,第2个都是嗯,请知晓今天的主题教育哈,公司也是啊已经发布了第1期的教育简报,啊总体来说都是第1期就是公布公司哈,啊在召开了主题教育的专题的1个那个啊工作。
|
||||
未知说话人02
|
||||
19:51
|
||||
好,第2个基层党组织哈,就是上次我们也开了哈,截止到3月15号,所有的基层党组织也开展了学习,后面我们再按照其那个动作来执行。好,因为呃主题教育,请大家知晓动作。第2个都是嗯,市公司也要求哈。
|
||||
未知说话人02
|
||||
20:06
|
||||
嗯,招待费哈要进行1个信息公开,哈,那块儿公开的对象和范围啊,都是本单位嗯管理层的那个嗯班子成员哈,那个范围哈。所以前期我们也是通过邮件的方式将25年啊,啊招待费的形式进行1个发布和公示,也完成了向纪检组织的啊报备。好,请领导知晓哈,这项工作已经完成。等我问一下,它那个公开是每年公开1次吗?还是每1次都要公开呀?每年1次,现在每年。
|
||||
未知说话人02
|
||||
20:38
|
||||
好,然后那个25年整体招待费使用的情况哈,嗯那个嗯也嗯做好做个汇报哈,25年哈,我们整体招待费的使用是超我们年初预算是14%哈,其中综合部哈是逐年增长哈,24年、25年哈逐年增长,嗯增长去非常明显哈,超预算也非常多哈,我们综合部去年超了107%,好所以26年的话也给综合部调整了预算哈,其他部门因为涉及到成本的管控哈,目前没有调整预算,嗯26年使用来看的话哈,目前也是综合部哈,嗯以及我们的市场部,市场部因为年初的渠道大会哈,啊整体它的那个时间节奏可能不太一样哈,包括我们超改分局和南京的分局哈,相对使用较快哈,是超过了时间进度,好其他一些部门的招待费预算力度啊,是是在进度范围之内,好可能更多的嗯要进行嗯特别提醒嘛,我觉得提醒啊整体可以嗯其实是有钱哈,在那个1个范围之内可以合理的规划,按时间进度哎,安排更多的同志哈,参与的同志都可以报哈,包括嗯因为之前我们也盘点的哈,嗯那个包括安运输中心
|
||||
未知说话人03
|
||||
22:00
|
||||
呃,情况的1个汇报和通报。看到的,给我说一下,就是关于政企部啊,因为我们的整个对外招待,集福来政企部啊。
|
||||
未知说话人03
|
||||
22:10
|
||||
这起步那边的话呀,因为有些重要单位又集中在个别的客户经理那边儿。
|
||||
未知说话人03
|
||||
22:16
|
||||
哦,所以说这种啊,要经历比较统筹。
|
||||
未知说话人03
|
||||
22:20
|
||||
那个统筹安排,你不能说1个客服经理。
|
||||
未知说话人03
|
||||
22:23
|
||||
太多,是吧?然后比如说,有像那种的,比如哎,哎,服务中心的那边的街坊啊,那些也可以,就大家分到分到来,哦,那边你跟和谐商量,把那个,就说实实在在去,是真实发生的费用啊,尽快的解决和。
|
||||
未知说话人03
|
||||
22:43
|
||||
不要拖,然后据我了解,去年子还有些费用都没还没完。
|
||||
未知说话人03
|
||||
22:47
|
||||
今天是油来了,是吧?
|
||||
未知说话人03
|
||||
22:49
|
||||
哦,那个事情呢,我认为它是个,不是个啥子大事情,不需要喊我们那个公公司领导市民来操心的那个事。
|
||||
未知说话人02
|
||||
23:01
|
||||
嗯,然后河川区发了1个通知哈,叫做河川区担当作为先进集体和先进个人。因为之前我们也报过河川强区啊企业的先进集体、先进个人,好目前还在区领导那里已经,嗯提交区领导1个,因为目前区领导还没得指示。好同时收到弄了1个通知,嗯那个文件的话相当于之前他的那个我们区的文件内容是,嗯区级的部门儿,啊单位以及区国资委啊管辖的企业。好因为今年呢,领导班子也特别提到计划我们要逐渐在河川区啊加强,嗯,叫做呢嗯增强我们区的影响力。所以我觉得那个可能也是1个点说,我们也单独进行了一些追踪和嗯询问哈那个下发单位哈,不是区委办啊,府办,嗯区委组织部以及区人力社保局啊,他们组建成了专班。好联系人是委办1个通知和人力社保局哈,看到他们他们是经办的那个负责发文的同志。好相当于嗯经过咨询1个,嗯争取到相当于我们,嗯如果有意意愿参加的话也可以参加。看了下前一届的那个评选名单呢,没得那种我们那种企业哈,都是政府的一些组织和机构。好那个
|
||||
未知说话人02
|
||||
24:23
|
||||
首先,因为它那个报名简单啊,就是报材料嘛,我们来签头写,就说看给不给合川移动1个资格啊。有那个资格的话呀,相当于可以差异化地与竞争对手拉开差距。目前竞争对手应该是对那个还是没有引起重视也没有动。啊,青云集团有三十多名。
|
||||
未知说话人02
|
||||
24:42
|
||||
有了名额嘛,去报嘛,啊,这是他的程序哈。嗯,要求的是3月31号之前哈,也是1个网上申请,需要进行1个报名。啊,所以用那个事情啊,下面都。
|
||||
未知说话人02
|
||||
24:53
|
||||
的回报。
|
||||
未知说话人02
|
||||
24:55
|
||||
啊,以上是综合部的汇报。
|
||||
未知说话人03
|
||||
25:00
|
||||
他达到啥子水平才能够担当?
|
||||
未知说话人02
|
||||
25:03
|
||||
啊,它跟我们平一样的,都是嗯。
|
||||
未知说话人02
|
||||
25:08
|
||||
那20个,类似于20个方身,都是文字型的。
|
||||
未知说话人02
|
||||
25:15
|
||||
不是。
|
||||
未知说话人02
|
||||
25:17
|
||||
就说工作突成绩突出,认真负责,类似于那种那种的,他都是套话。所以说那种东西,它主要还是在于。
|
||||
未知说话人02
|
||||
25:27
|
||||
给不给你的革命呢?
|
||||
未知说话人02
|
||||
25:30
|
||||
负责的是尾巴还是社保局?他们是联合工作组,通知里头有尾巴和社保局2个联系单位,应该是他们2个都在。
|
||||
未知说话人02
|
||||
25:39
|
||||
啊,相当于突出的评选都是政治忠诚可靠啊,担当过硬啊,都是套话这个。套话。哎,所以那个工作成绩突出啊,什么,嗯,整体形象好啊,然后那个纪律严明,就像强区那个一样,实际上他也是那种历史套话。啊,所以说那块儿的话,我个人觉得还是从今历史判断来看,还是要有有推荐,然后你再去报,不然的话确实有点浪费。
|
||||
未知说话人02
|
||||
26:06
|
||||
啊,那块儿是委办室叫陈红同志,啊,然后人力资源局是叫崔磊同志,也跟他们联系了,他们说他们都是发会议的,具体经办呢。
|
||||
未知说话人02
|
||||
26:16
|
||||
收入跟那个差距。
|
||||
未知说话人02
|
||||
26:21
|
||||
嗯,没得,没问到。你要去了解噻。哎,都是可能看那块儿是正气气了解。就是有有有。行政区可能都是,就是讲它那边主要那个方面,是吧?然后它那个是哪1个。
|
||||
未知说话人03
|
||||
26:33
|
||||
尾巴是是那个。
|
||||
未知说话人02
|
||||
26:37
|
||||
对的,我都说建议争取跟能联系,因为我们问了他们的,他说我是发会议的,我不清楚,让我鼓捣他去问呢,对不?也不太高兴。嗯。
|
||||
未知说话人03
|
||||
26:47
|
||||
那个我们没得好大好大的那个的话,我们去花那个时间也没得好大意义的。学校的练习有。
|
||||
未知说话人02
|
||||
26:55
|
||||
我印象中好像,那是发通报的时候。
|
||||
未知说话人03
|
||||
26:58
|
||||
好像有1个员工还有个,我说你们去了解一下,如果是那种的话,我们也可以跟这边的领导先沟通一下。
|
||||
未知说话人03
|
||||
27:06
|
||||
但是我现在不晓得是哪个领导在负责那个事儿。
|
||||
未知说话人03
|
||||
27:09
|
||||
因为你至少是委办主任那那个层面嘛,或者是或者是分管那个领导嘛,去单独去了解,好吧。他们如果,如果有那个的话,我们去去争取多,确实,别个都是拼的区头的,啊,我们也不用花那个时间。
|
||||
未知说话人03
|
||||
27:25
|
||||
是吧?了解是吧?
|
||||
未知说话人03
|
||||
27:29
|
||||
今儿不是聊天。
|
||||
未知说话人01
|
||||
27:32
|
||||
那个你那个整个三期要的第2期的工作做1个嗯,项目汇报。现在是拆迁方面,我们整个刚刚去在了解的,我们一些那个拆迁,目前已经完成了1145。好,整个还有呢是。嗯,拆迁方式我们那个通过当通过那个注册那个单位上,那么逐步好那个,嗯,做510000的价值提升,都是他原来的通货,没有达到50的我们提升到50。好,那么那个会议还有里面有好多个成员都可以说那个收入。好,那么还有1个都是,就是我们办理那个比如说新业不拆迁都是2次通货,15.1元个月。我们做了2个2次通货,都是1个1个那个整体层面的1个拆迁。好,那么党建网拆迁都是我们的那个,那个新增的通货。好,包括有文化套餐,好做了那个他会一笔一笔进行进行算。好,就是一季度的整个整个拆迁是主要的,还是在通货场景,我们原来的通货没达到50的,做一些新的价值提升,说完成率啊,成绩比较好。那个是整个拆迁1个情况。好,那么在在整个历史融合在在这些包括上面呢,那个会议的那个政府那个啊,还是继续
|
||||
未知说话人01
|
||||
30:23
|
||||
嗯,单位上集中做的啊,是和前方在那个,还有京东他们说也也有一些社区做的啊,那种家庭的清洗,和我们那个相结合嘛,两种方式做点看,看哪种效果好。因为像在社区做的啊,我们就像比如说像区区委组织部家属院,建设要家属院小区,啊那种和单位客户比较集中的小区啊,我们去开展一些,一些单位上的客户,一些服务工作。啊那么在也是做的啊,本周的1个做的情况,本周做的啊一共开展了五场,啊那个落实相对较好,那个业务量的话也还是没有达到我们想要的成果好,特别是在在落实上面的签约好,其他的方案的话,集资签约的板块的话,那边我在本周啊还要进行1个加强。
|
||||
未知说话人01
|
||||
31:04
|
||||
啊,商客市场1个情况,整个整个商客的话,到了我们到了2月份,收入是88.5,好比上个一期增加了10000。好完成较好的是超改,那个城北和南京改增幅都上了20000,好一家农家乐出现了负200块钱的1个情况。啊,整体个商客的1个规模情况和那个都还是比较好。啊,那个在价值拓展方面的话,我们是完成了115。好同的是第6和下一期我再把其他公司做1个展示。因为因为那个我们我仅分全县的问题,目前只能看到个的。好排名是找上市公司个的。好,我下一期把那个整个全市的1个排名,好做1个展现。
|
||||
未知说话人01
|
||||
31:40
|
||||
那个是整个价值拓展的1个情况。
|
||||
未知说话人01
|
||||
31:44
|
||||
啊,他那个重点的工作啊,都在商客经理方面的话,整个,啊,目前我们还有2个人。嗯,那是以周为单位,周为单位,曾会流的话,那个星期他的他的那个基础业务只有两笔,所以说相对于较差一点。我们是以周为单位在在统计,我下期把累计的嗯按累计来嘛。
|
||||
未知说话人01
|
||||
32:05
|
||||
它那个是整个材料会吧。
|
||||
未知说话人04
|
||||
32:13
|
||||
只需要。
|
||||
未知说话人04
|
||||
32:15
|
||||
我份工作还有没得?
|
||||
未知说话人05
|
||||
32:20
|
||||
在种。
|
||||
未知说话人05
|
||||
32:22
|
||||
第1次建委那边哈,那个几十铺哈。
|
||||
未知说话人05
|
||||
32:25
|
||||
之前有个那个。
|
||||
未知说话人05
|
||||
32:27
|
||||
想的也。
|
||||
未知说话人06
|
||||
32:31
|
||||
那个。
|
||||
未知说话人06
|
||||
32:33
|
||||
咸鱼粉。
|
||||
未知说话人06
|
||||
32:36
|
||||
每个单位长一些,大约啥子?
|
||||
未知说话人06
|
||||
32:39
|
||||
我先模仿一下。
|
||||
未知说话人05
|
||||
32:42
|
||||
第2关,然后再次接放大,是那样的。
|
||||
未知说话人05
|
||||
32:47
|
||||
就可以上清华,反正第2天你已经理了一些哈,我觉得能够把那个。
|
||||
未知说话人05
|
||||
32:51
|
||||
公司人也很少的。
|
||||
未知说话人05
|
||||
32:55
|
||||
进一步结合地方的改造。
|
||||
未知说话人05
|
||||
32:59
|
||||
那个。
|
||||
未知说话人05
|
||||
33:00
|
||||
厨房的一些。
|
||||
未知说话人05
|
||||
33:06
|
||||
第2就是,建委今年那个综合评估体系已经出来了。
|
||||
未知说话人05
|
||||
33:11
|
||||
不知道怎么了。
|
||||
未知说话人05
|
||||
33:12
|
||||
把前面。
|
||||
未知说话人05
|
||||
33:15
|
||||
疗效。
|
||||
未知说话人05
|
||||
33:19
|
||||
啊第2个关于正畸康复,包括运输,已经7号就说了,第1个点。
|
||||
未知说话人05
|
||||
33:24
|
||||
上海人多。
|
||||
未知说话人05
|
||||
33:26
|
||||
经理要当天处理,及时回复。
|
||||
未知说话人05
|
||||
33:30
|
||||
像刚才,中国不同宝的。
|
||||
未知说话人05
|
||||
33:32
|
||||
那个建伟部主儿,肯定是收到,跟到给我回复,把事情是完结了。
|
||||
未知说话人05
|
||||
33:37
|
||||
啊,我们这几块儿的经理基本上也不在那个板块的站。
|
||||
未知说话人05
|
||||
33:41
|
||||
哦,也不好意思啊,我在会议上说了,私下也说了很多次了。
|
||||
未知说话人05
|
||||
33:45
|
||||
要养成那种日日日清、日清日结、日结日高的好习惯。
|
||||
未知说话人05
|
||||
33:51
|
||||
就算没完成,阶段性的来沟通一下儿,有什么问题困难,我们一起来想办法推进。
|
||||
未知说话人05
|
||||
33:57
|
||||
你不能1个事情,有些工作一说几个月都还是还没做。
|
||||
未知说话人05
|
||||
34:04
|
||||
回复工作是首先回复安排工作的领导。
|
||||
未知说话人05
|
||||
34:09
|
||||
而不是去肉包的时候会不丰富。
|
||||
未知说话人05
|
||||
34:12
|
||||
我要养成好习惯,动作要推得早。
|
||||
未知说话人05
|
||||
34:15
|
||||
不好意思啊,我都不知道得罪儿童怎么。
|
||||
未知说话人05
|
||||
34:18
|
||||
我都当是我的嘛。
|
||||
未知说话人05
|
||||
34:21
|
||||
并且恢复工作一定是要量化的。
|
||||
未知说话人05
|
||||
34:24
|
||||
要有结果。
|
||||
未知说话人05
|
||||
34:26
|
||||
要有措施,要有成效。
|
||||
未知说话人05
|
||||
34:33
|
||||
第2,关于上课这个指标,我也说了很多次了,我们没看到具体的保障措施。只有最后1周了,早上上班的时候也跟廖经理做了沟通,需要拿出具体可行的方案。
|
||||
未知说话人05
|
||||
34:47
|
||||
那个1月5号那天,我就说了,是结合专线。
|
||||
未知说话人05
|
||||
34:51
|
||||
助账账客单位的业务发展。
|
||||
未知说话人05
|
||||
34:56
|
||||
各项指标都会好,方法我也教了,也没看到动作出来。
|
||||
未知说话人05
|
||||
35:01
|
||||
你没看到回复。
|
||||
未知说话人05
|
||||
35:04
|
||||
请今天要给我1个具体的回复:哪个能保证那项指标达成?
|
||||
未知说话人05
|
||||
35:13
|
||||
重新想啊,其他东西。
|
||||
未知说话人03
|
||||
35:19
|
||||
关于那个市场部的工作说。
|
||||
未知说话人03
|
||||
35:22
|
||||
3个方面,第1个方面就是。
|
||||
未知说话人03
|
||||
35:26
|
||||
整个1个资料的1个存储安排,就是。
|
||||
未知说话人03
|
||||
35:29
|
||||
1个是本季度,本本季度的1个1个1个收官之日。
|
||||
未知说话人03
|
||||
35:34
|
||||
刚才谈电脑,按照目标来推。
|
||||
未知说话人03
|
||||
35:38
|
||||
治疗的第2个,像小方面都是,基本上那个周也是。
|
||||
未知说话人03
|
||||
35:43
|
||||
最后1周了。
|
||||
未知说话人03
|
||||
35:45
|
||||
本本季度都是新区营销不厚,我觉得完了过后还是有一些按部就班的一些,大家有点皮,包括那个整个业务推进,市场方面也比较也比较皮软。
|
||||
未知说话人03
|
||||
35:57
|
||||
呃,请商户提前谋划。
|
||||
未知说话人03
|
||||
35:59
|
||||
二级部的1个业务活动,那把生日。
|
||||
未知说话人03
|
||||
36:04
|
||||
不能说二季度是传统的淡季。
|
||||
未知说话人03
|
||||
36:08
|
||||
不管是我的签约也好,商人也好,H也好,还是那个AI军团也好,那个业务活动的那个升职还是要要造起来哈。
|
||||
未知说话人03
|
||||
36:19
|
||||
电脑上不提。
|
||||
未知说话人03
|
||||
36:21
|
||||
第2个方面就是那个,呃上周那个根据我看那个能力地图收入地图已经已经发过来了。
|
||||
未知说话人03
|
||||
36:28
|
||||
呃,请那个商务部去到中心。
|
||||
未知说话人03
|
||||
36:32
|
||||
馆主。
|
||||
未知说话人03
|
||||
36:34
|
||||
本周内,把涉及到销售能力的几个事情的进度。
|
||||
未知说话人03
|
||||
36:40
|
||||
给我做1次报告,1个是招聘的情况。
|
||||
未知说话人03
|
||||
36:44
|
||||
第2个是农村渠道的。那个
|
||||
未知说话人03
|
||||
36:47
|
||||
进度,第3个是上周营销那个事情。
|
||||
未知说话人03
|
||||
36:52
|
||||
他没在1个。
|
||||
未知说话人03
|
||||
36:53
|
||||
具体的方案,西消队伍建设和转型,本周内给我1个这3个事情。
|
||||
未知说话人03
|
||||
37:00
|
||||
做个1次汇报。
|
||||
未知说话人03
|
||||
37:03
|
||||
3个字,蚂蚁多。
|
||||
未知说话人03
|
||||
37:06
|
||||
满意度这1次满意度的测评结果,上周五,林哥说了个话。
|
||||
未知说话人03
|
||||
37:13
|
||||
我当时问,还是觉得这个事情,不管从我还是。
|
||||
未知说话人03
|
||||
37:18
|
||||
商务部和政企部,这个工作确实是。
|
||||
未知说话人03
|
||||
37:22
|
||||
有烛火。
|
||||
未知说话人03
|
||||
37:27
|
||||
这次是那个,都是,应该是最后,就是按照老的方式来测评嘛。
|
||||
未知说话人03
|
||||
37:33
|
||||
下1块就是用啊,用后机评来测评啊。
|
||||
未知说话人03
|
||||
37:36
|
||||
3月份还有。
|
||||
未知说话人02
|
||||
37:38
|
||||
有前期的,没就会咯。但前期不会在错。
|
||||
未知说话人03
|
||||
37:44
|
||||
所以说这个事情,我觉得,但是真的要反思一下儿。
|
||||
未知说话人03
|
||||
37:49
|
||||
满一度的工作,你是做了吗?还是做到了?
|
||||
未知说话人03
|
||||
37:55
|
||||
正起步之前,都是我们满一做了1个1个拉分项,1个开卷考试。廖经理是不是思想上松懈了?因为除了夏总参加的客户会,我看到廖经理之外,其他次的客户会廖经理都不在。
|
||||
未知说话人03
|
||||
38:11
|
||||
都是1个,都是1个货开卷儿炸。
|
||||
未知说话人03
|
||||
38:15
|
||||
我觉得这个事情你应该是可控的,你才不,你才不关注这个事情。
|
||||
未知说话人03
|
||||
38:23
|
||||
补充句啊,近期不要主观对这个。
|
||||
未知说话人03
|
||||
38:27
|
||||
除廖经理以外,你们哪个主管对郑启满队负责?
|
||||
未知说话人03
|
||||
38:31
|
||||
我支持好看点吧。
|
||||
未知说话人03
|
||||
38:34
|
||||
我上次上次不是跟廖经理说的,如果说货款有,这个我们就抓起来啊,让他亲自抓。
|
||||
未知说话人07
|
||||
38:50
|
||||
麻烦等会儿,那个。
|
||||
未知说话人07
|
||||
38:52
|
||||
我觉得现在就是叫啥子啊,亡羊补牢为时未晚,这个事情现在还有。
|
||||
未知说话人07
|
||||
39:00
|
||||
还有时间,但是我觉得市场不和自己。
|
||||
未知说话人07
|
||||
39:05
|
||||
在在抓这个工作的时候,老师出了问题才重视,才才反转,才抓微笑曲线。我觉得这种工作方式和工作态度,你说我们要反思一下。
|
||||
未知说话人07
|
||||
39:17
|
||||
另外就是关于那个,就是客户的工作,中中国的时候我也跟跟那个。
|
||||
未知说话人07
|
||||
39:24
|
||||
财务部的领导做的够好,嗯,有几点。
|
||||
未知说话人07
|
||||
39:28
|
||||
也是同步市场部,也是给项目做1个做。
|
||||
未知说话人07
|
||||
39:32
|
||||
就是那个第1个,都是八零的两率。
|
||||
未知说话人07
|
||||
39:36
|
||||
就是到3月底,特别是3月底,就这个话,关键门儿说,市公司会有统一。
|
||||
未知说话人07
|
||||
39:44
|
||||
是不是会通用?所以说,就是它的满意的样板儿。
|
||||
未知说话人07
|
||||
39:48
|
||||
下来就是你跟那个小付一起,在我办公室我们讨论一下,满意客户满意的样板一定要按照四公司的规定来。
|
||||
未知说话人07
|
||||
39:58
|
||||
第2个是对于不满的客户。
|
||||
未知说话人07
|
||||
40:03
|
||||
它有2个时间节点,1个是五点半,1个是五点五点半过后。
|
||||
未知说话人07
|
||||
40:08
|
||||
还有五点半有几个操作的1个,有1个有个技巧。同时不满的客户要报警客户。因为现在不是这个指标不是KPK考核集团的,但是啊总是要求的,要考核分公司的。所以说这个事情,在操作上面是有空间的。
|
||||
未知说话人07
|
||||
40:32
|
||||
然后那个80200000000,我也看。
|
||||
未知说话人07
|
||||
40:36
|
||||
那还是不要,我们目前是属于一类的,到属于第2的左右。
|
||||
未知说话人07
|
||||
40:42
|
||||
也是也是不是低于全市的平均,所以说我觉得这个事情也是没有快速的把市公司的有一些技巧性的动作启动。
|
||||
未知说话人07
|
||||
40:58
|
||||
好,在考题上面都是八零两率,是有打印后面的。
|
||||
未知说话人07
|
||||
41:04
|
||||
这个是可以,是个是可以来平衡的。
|
||||
未知说话人07
|
||||
41:08
|
||||
好,这块儿的话,就是请那个。
|
||||
未知说话人07
|
||||
41:11
|
||||
商户,把每天的那个,就是每天,就是到到月底之前,每天微信上面出个日报。
|
||||
未知说话人07
|
||||
41:21
|
||||
发送给发给我和小红嘛。
|
||||
未知说话人07
|
||||
41:25
|
||||
然后,然后高关于考核,我也大概问了一下。
|
||||
未知说话人07
|
||||
41:29
|
||||
嗯,法律两界还是有那个,就是有可能有比较。
|
||||
未知说话人07
|
||||
41:33
|
||||
有可能又不高,也没说定。今年的KPAN考还基本上定了,是工信部的有责。
|
||||
未知说话人07
|
||||
41:40
|
||||
要考KPI啊,还有就是你的网率,就是跟满意度相关的,客户不走,就是按照那个观点,驾驶提升,就你的网率不高于去年,你应该是个,你应该是会拿个KPI来考核。
|
||||
未知说话人08
|
||||
41:57
|
||||
应该是1个,就是。
|
||||
未知说话人08
|
||||
42:00
|
||||
目前都是定了的,就是2个考核:1个是工信部有责,1个是。
|
||||
未知说话人08
|
||||
42:04
|
||||
都去。
|
||||
未知说话人07
|
||||
42:06
|
||||
8.2月是8.2月是有有打印。
|
||||
未知说话人07
|
||||
42:11
|
||||
大概是这个样子,所以说把那个考核的情况你进一步再去摸细,还有那些都是可以可控的操作的一些动作。
|
||||
未知说话人07
|
||||
42:23
|
||||
跟子公司的话。
|
||||
未知说话人07
|
||||
42:27
|
||||
对吧?商务部都说的3个方面,商务部的话,我们最关注是把运动会、本周运动会。
|
||||
未知说话人07
|
||||
42:33
|
||||
对朱子豪。
|
||||
未知说话人07
|
||||
42:35
|
||||
嗯,我是星期跟下午到了,我要星期星期星期三、星期四出差,星期五到时候。
|
||||
未知说话人07
|
||||
42:43
|
||||
然后有啥事情,就是给我报告的事情。如果是来点计划,就明天明天,明儿下午,反正说几个事情。
|
||||
未知说话人07
|
||||
42:53
|
||||
给我汇报,如果来不及的话,都都用视频。好,星期星期五上午。
|
||||
未知说话人09
|
||||
43:06
|
||||
红火亮的樱桃。
|
||||
未知说话人10
|
||||
43:11
|
||||
KPI。
|
||||
未知说话人10
|
||||
43:13
|
||||
刚才会上我们也过了1遍,按照我们定好的目标,确保完成。
|
||||
未知说话人10
|
||||
43:20
|
||||
好,马云的话。
|
||||
未知说话人10
|
||||
43:22
|
||||
具体的一些情况,请你们这个会后。
|
||||
未知说话人10
|
||||
43:27
|
||||
1个详细规划。
|
||||
未知说话人10
|
||||
43:29
|
||||
啊,我想强调的是。
|
||||
未知说话人10
|
||||
43:32
|
||||
自信的。
|
||||
未知说话人10
|
||||
43:34
|
||||
我觉得,不管是部门儿还是。
|
||||
未知说话人10
|
||||
43:38
|
||||
不管是部门经理,还是主管,还是具体抓工作的人,和每1个一线的同志们,大家都要有那个执行力。
|
||||
未知说话人10
|
||||
43:47
|
||||
事情要办法,事不做好。
|
||||
未知说话人10
|
||||
43:52
|
||||
要知道怎么做,但是就是不去做。
|
||||
未知说话人10
|
||||
43:56
|
||||
那我觉得那是我们公司至少。
|
||||
未知说话人10
|
||||
43:59
|
||||
我们班子几个人是,我相信都不认可的那种工作作风。
|
||||
未知说话人10
|
||||
44:10
|
||||
好,还有4公司的那个年度考核。
|
||||
未知说话人10
|
||||
44:13
|
||||
觉得几个部门主要是去了解情况啊,那个提前也给你们给说过几次。
|
||||
未知说话人10
|
||||
44:19
|
||||
啊,如果有。
|
||||
未知说话人10
|
||||
44:21
|
||||
对我们影响比较大的一些病毒,或者是。
|
||||
未知说话人10
|
||||
44:25
|
||||
你要提前讲,不要等到起那个,别个都定好了再来跟我说,夏总,那个考核是今年子我们要照。
|
||||
未知说话人10
|
||||
44:34
|
||||
对,我说很。
|
||||
未知说话人10
|
||||
44:37
|
||||
我们把工作做在前面,你们细细了解。我其实有点担心2个哈,1个是。
|
||||
未知说话人10
|
||||
44:43
|
||||
1个叫啥子啊?那个阿布咖啡。
|
||||
未知说话人10
|
||||
44:46
|
||||
那个全市,那个集团公司有1个啥子阿普提升,啥子考的,我不知道他怎么考,我不清楚。
|
||||
未知说话人10
|
||||
44:53
|
||||
很默契。
|
||||
未知说话人10
|
||||
44:55
|
||||
提升或者改善,或者啥,阿婆的啥子啥子。
|
||||
未知说话人10
|
||||
44:58
|
||||
我觉得那个对,我我们公司,我不知道说不有。
|
||||
未知说话人10
|
||||
45:02
|
||||
我们要去,不管哪个样子,我觉得考核,我们其实我们不要求上市公司好像要要要对其他公司有啥子。
|
||||
未知说话人10
|
||||
45:10
|
||||
我要去想那些事情,但是至少是比较公平的。我们通过努力,我们可以去进行1个得乎点儿改善的。
|
||||
未知说话人10
|
||||
45:18
|
||||
最主要单位。
|
||||
未知说话人10
|
||||
45:20
|
||||
有提醒过,我我那边的话也会。
|
||||
未知说话人10
|
||||
45:24
|
||||
好,2个分管领导里面的话,也跟他们2个主要部门嘛,政企部跟。
|
||||
未知说话人10
|
||||
45:29
|
||||
他说:“我们加强力度嘛,然后如果确实有有必要的话,哈,我们可以去。”
|
||||
未知说话人10
|
||||
45:35
|
||||
也是。
|
||||
未知说话人10
|
||||
45:36
|
||||
好,那些沟通。
|
||||
未知说话人10
|
||||
45:39
|
||||
是1个年龄的1个非常重要的一点啊,不要开始我们处在起跑线上,那个很麻烦,不像我印象我们当时那个近视还在有1年,说我们那个啥子。
|
||||
未知说话人10
|
||||
45:50
|
||||
心也不靠海,是吧?
|
||||
未知说话人10
|
||||
45:53
|
||||
开始都是主要在细胞线上面,啊,最开始为啥子不够通行?有那种卡位口结和那些。
|
||||
未知说话人10
|
||||
45:59
|
||||
是吧?我也相信,市公司他也应该会考虑分公司的整体情况,然后统筹来,至少大家都能够调高摸得度,是吧?
|
||||
未知说话人10
|
||||
46:14
|
||||
今天的周会就到这儿结束。
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
|
||||
|
||||
## 📝 会议概述
|
||||
[会议聚焦通信网络运维、商客市场拓展及综合行政管理。当前处于季度收官冲刺阶段,主要议题涵盖宽带安装进度追踪、运维KPI达标情况、90工程转化率与退单流程优化、PCDN专线与基站巡检进展、满意度考核部署及行政后勤统筹。预期交付成果为明确各项指标阶段性目标、优化审批考核机制、落实季度收官方案及运动会方阵人员调配计划。]
|
||||
|
||||
## 🚀 核心议题
|
||||
|
||||
### 议题1:宽带上门量与安装进度分析
|
||||
- 需求分析: [需平衡兼顾安装与维护上门量,累计进度35%,距离3000户目标稍显靠后;周均安装与维护上门量合计约1000单]
|
||||
- 技术评估: [受降雨影响当周上门量仍达580单;弱光整改率目前0.51持续向好,即将达成0.5目标;FPTR指标已达标]
|
||||
- 资源规划: [建议将终端指标压降纳入运维考核,每季度设定阶段性目标,否则全市难以达成年度5.5目标]
|
||||
|
||||
### 议题2:90工程转化率与退单流程优化
|
||||
- 设计方案: [月度转化率87.35%(目标90%),当周受天气影响仅80%;退单率6.53%(目标低于7.5%)]
|
||||
- 原型验证: [退单主因:用户不安装16单、长期无法施工3单、入错单4单;B2C退单率44.29%主因协调问题]
|
||||
- 标准制定: [优化退单审批流程,一线审批同意应予以提出,避免主观随意性;该指标纳入综合运维考核]
|
||||
|
||||
### 议题3:PCDN专线管控与基站/专线巡检进展
|
||||
- 开发进度: [长停/单停工单全部达标;118条专线存量73条已巡检56条,未验收45条已全巡检,预计3月底全量完成;动环指标保持良好]
|
||||
- 技术难点: [PCDN专线受开学影响降至4.84,物业点天线待4月初检测;上周3个超标基站因开关电源故障/光纤衰耗过大已恢复]
|
||||
- 测试策略: [上报涉及出口的学校IP对接市公司建立限速机制;客诉机房机柜问题清单本周全量发给客服经理跟进处理]
|
||||
|
||||
## ❓ 关键问答
|
||||
|
||||
Q: 针对B2C退单率偏高及退单随意性问题,如何优化管理流程?
|
||||
A: 建议施工方优化退单审批流程,若一线审批同意应及时提出,避免个人主观意识导致退单,并将该指标纳入综合运维考核进行严格管控。
|
||||
|
||||
---
|
||||
|
||||
Q: 针对近期满意度测评结果不佳及80/20两率考核要求,市场与政企部门如何落实?
|
||||
A: 要求政企部反思工作态度,亡羊补牢;月底前每日微信出日报,确保离网率与满意度挂钩KPI考核不低于全市平均,并快速启动市公司管控技巧动作。
|
||||
|
||||
## 💡 重要观点
|
||||
|
||||
### 关于产品定位
|
||||
> "商客市场2月收入88.5万(环比增1万),价值拓展完成115,但商客经理仅2人导致基础业务较差,需补充人员并提前谋划二季度业务声势。"
|
||||
|
||||
### 关于技术选型
|
||||
> "针对PCDN专线指标恶化,需对接市公司建立学校出口IP限速机制,物业点天线检测预计4月初完成,其余PCDN指标均达标,需持续监控出口带宽。"
|
||||
|
||||
### 关于用户体验
|
||||
> "满意度工作需全员重视,政企部存在思想松懈;市公司统一要求80/20两率考核,离网率与满意度挂钩,需采取可控动作确保不低于全市平均。"
|
||||
|
||||
### 关于商业价值
|
||||
> "25年招待费整体超年初预算14%,综合部去年超107%已调整;要求统筹分摊政企招待集中问题,清理历史未结清费用,工会经费严格考核以'用更少钱办更好事'。"
|
||||
|
||||
### 核心共识
|
||||
> "强化全员执行力,事不做好需反思;年度考核需提前预警大变量与风险,市公司统筹考核力求公平,各部门需加强沟通统筹,确保各项工作扎实落地。"
|
||||
|
||||
## 📊 开发决策
|
||||
|
||||
- 技术决策: [确定对接市公司建立PCDN学校出口限速机制;网络质量综合评估体系已下发,下周进行指标分解和目标制定]
|
||||
- 功能决策: [优先推进90工程转化率提升与退单流程优化;暂缓非紧急行政事项,聚焦季度收官与满意度考核达标]
|
||||
- 资源决策: [运动会方阵缺编9人,要求各部门今日确定补员名单;食堂改造预算约29.8万待审计,直饮机方案报市公司待批下半年引入]
|
||||
|
||||
## 📌 后续行动
|
||||
|
||||
- [ ] 本周内完成90工程转化率提升具体方案及退单审批流程优化,正式纳入运维考核
|
||||
- [ ] 对接市公司落实PCDN学校出口IP限速机制,4月初完成物业点天线检测
|
||||
- [ ] 3月底前完成118条专线全量巡检,本周内将机房机柜客诉问题清单全量发给客服经理
|
||||
- [ ] 4月15日前完成212座二级基站全量拆除、下电及专线资源与电费服务费调整
|
||||
- [ ] 今日确定运动会方阵补员9人名单,周二至周四下班后排练,周五参加活动
|
||||
- [ ] 商务部本周内汇报招聘情况、农村渠道进度及上周营销事情方案;市场部每日微信出80/20两率日报
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
{
|
||||
"sub_topics": [
|
||||
{
|
||||
"title": "宽带上门量与安装进度分析",
|
||||
"time_interval": "00:01-01:17",
|
||||
"overview": "会议首先分析了宽带工作的上门量与安装进度。受上周降雨影响,当周上门量仍达580单,累计进度为35%,距离3000户目标稍显靠后。周均安装与维护上门量合计约1000单,需继续平衡兼顾安装与维护需求。"
|
||||
},
|
||||
{
|
||||
"title": "上门后关键运维指标通报",
|
||||
"time_interval": "01:17-02:07",
|
||||
"overview": "接着通报上门后关键运维指标情况。弱光整改率目前为0.51,持续向好并接近0.5目标;FPTR指标已达标。但终端指标需压降至5.5,主动过境指标仅0.3进度靠后,建议纳入运维考核并设定季度阶段性目标。"
|
||||
},
|
||||
{
|
||||
"title": "90工程转化率与退单原因分析",
|
||||
"time_interval": "02:07-03:07",
|
||||
"overview": "随后重点讨论了90工程转化率与退单率数据。月度转化率87.35%(目标90%),受天气影响当周仅80%;退单率6.53%(目标低于7.5%)。退单主因包括用户不安装(16单)、长期无法施工、入错单及天气影响,其中B2C退单率较高。"
|
||||
},
|
||||
{
|
||||
"title": "退单流程优化与考核机制建议",
|
||||
"time_interval": "03:07-03:53",
|
||||
"overview": "针对退单问题提出流程优化与考核建议。因协调问题导致B2C退单率偏高,建议施工方优化退单审批流程,避免一线随意退单及主观意识影响。该指标将纳入综合运维考核,要求审批同意后及时提出,减少退单随意性。"
|
||||
},
|
||||
{
|
||||
"title": "PCDN专线指标与学校限速机制推进",
|
||||
"time_interval": "03:53-05:33",
|
||||
"overview": "会议分析了PCDN专线指标恶化及应对措施。受3月学校开学影响,专线指标降至4.84,已上报涉及出口的学校IP并对接市公司建立限速机制。物业点天线检测预计4月初完成,其余PCDN指标均达标。"
|
||||
},
|
||||
{
|
||||
"title": "基站故障处理与单停/长停工单进展",
|
||||
"time_interval": "05:33-06:32",
|
||||
"overview": "通报了基站故障处理与单停/长停工单进展。长停/单停工单全部达标,上周发现的3个超标基站已分别因开关电源故障和光纤衰耗过大处理恢复。旁站及基站故障处理率持续较低,12项自办工作含部分电话漏接问题需关注。"
|
||||
},
|
||||
{
|
||||
"title": "专线护航巡检与客诉处理通报",
|
||||
"time_interval": "06:32-07:57",
|
||||
"overview": "专线护航巡检与客诉处理情况得到汇报。118条专线中存量73条已巡检56条,未验收45条已全量巡检,预计3月底按时完成。客诉主要源于机房和机柜问题,本周将把问题清单全量发给客服经理以便沟通处理。"
|
||||
},
|
||||
{
|
||||
"title": "动环指标、基站拆除与网络质量评估体系",
|
||||
"time_interval": "07:57-09:12",
|
||||
"overview": "动环指标与基站资源调整进展顺利。动环指标保持良好并在全市交流分享;金沙管家二级基站剩余212座,已下电并累计拆除46座,预计4月15日前全量完成拆除及电费调整。网络质量综合评估体系已下发,下周将分解指标制定目标。"
|
||||
},
|
||||
{
|
||||
"title": "25年重点专项工作推进与行政事务进展",
|
||||
"time_interval": "09:12-12:40",
|
||||
"overview": "25年重点专项工作推进与行政事务取得阶段性成果。花果山项目无变化,微投/无人机项目计划本周推动验收。建委清单、市场终端占比汇报及政企收入地图已提交。打印机事宜已协调收回1台并洽谈周边打印店,确保招投标打印质量与成本可控。"
|
||||
},
|
||||
{
|
||||
"title": "综合管理通报(工会经费、食堂改造与直饮机)",
|
||||
"time_interval": "12:40-15:21",
|
||||
"overview": "综合管理通报聚焦工会经费压减与后勤改造。3月20日召开工会面对面沟通会,今年经费将严格考核。柔性工程确定更衣室改造及预算约29.8万的食堂改造(待审计),直饮机方案已报市公司待批,预计下半年引入以节约成本。"
|
||||
},
|
||||
{
|
||||
"title": "幸福一家亲活动与运动会方阵人员筹备",
|
||||
"time_interval": "15:21-19:36",
|
||||
"overview": "幸福一家亲活动筹备与运动会方阵人员调度。全年计划组织6场大型体育活动,但因主力队员肌肉拉伤无法参赛,方阵现缺编9人。需各部门今日确定补员名单以购买服装,周二至周四下班后排练,周五参加活动可获得绩效加分。"
|
||||
},
|
||||
{
|
||||
"title": "主题教育、招待费公开与历史费用清理统筹",
|
||||
"time_interval": "19:36-22:47",
|
||||
"overview": "主题教育、招待费公开与历史费用清理统筹部署。基层党组织学习已全覆盖,25年招待费整体超年初预算14%,综合部去年超预算107%已调整。针对政企部招待集中问题,要求统筹分摊至服务中心等部门,彻底清理去年未结清费用,避免拖延。"
|
||||
},
|
||||
{
|
||||
"title": "合川区担当作为先进评选报名策略",
|
||||
"time_interval": "22:47-27:32",
|
||||
"overview": "合川区担当作为先进评选报名策略讨论。区委办等部门发文,3月31日前需网上申请,目前竞争对手未重视。鉴于评选标准多为套话且存在名额倾向性,建议先联系委办及人社局经办人摸底确认资格与倾向,避免盲目报名浪费资源。"
|
||||
},
|
||||
{
|
||||
"title": "二期项目拆迁进展与商客市场收入汇报",
|
||||
"time_interval": "27:32-31:44",
|
||||
"overview": "二期项目拆迁进展与商客市场收入汇报。拆迁已完成1145户,通过政企推进原套餐未达50元的价值提升至50元,新业务办理2次套餐(15.1元/月)。商客2月收入88.5万(环比增1万),价值拓展完成115,但商客经理仅2人导致基础业务较差,下期将改为累计统计。"
|
||||
},
|
||||
{
|
||||
"title": "政企工作纪律要求与上量指标方案落实",
|
||||
"time_interval": "31:44-35:19",
|
||||
"overview": "政企工作纪律要求与上量指标方案落实。建委综合评估体系已出,政企客单位业务发展需经理当天处理回复,养成日清日结习惯。回复需量化、有结果与措施成效,上量指标缺乏具体措施,需本周拿出可行方案。"
|
||||
},
|
||||
{
|
||||
"title": "市场部季度收官规划与满意度测评反思",
|
||||
"time_interval": "35:19-39:05",
|
||||
"overview": "市场部季度收官规划与满意度测评反思。二季度勿视作传统淡季,需提前谋划并造业务声势。针对近期满意度测评结果不佳,指出政企部存在思想松懈问题,要求反思工作态度并亡羊补牢。商务部需在本周内汇报招聘、农村渠道及营销事情进度。"
|
||||
},
|
||||
{
|
||||
"title": "满意度80/20两率考核要求与日报机制",
|
||||
"time_interval": "39:05-42:06",
|
||||
"overview": "满意度80/20两率考核要求与日报机制落实。市公司统一要求月底前每日微信出日报,离网率与满意度挂钩KPI考核。要求采取可控动作确保不低于全市平均,市场部需快速启动市公司技巧动作。领导出差期间需提前安排汇报事宜。"
|
||||
},
|
||||
{
|
||||
"title": "年度考核风险预警与执行力总结",
|
||||
"time_interval": "42:06-46:14",
|
||||
"overview": "年度考核风险预警与全员执行力强调。会议最后强调四公司年度考核需提前预警大变量与风险,市公司统筹考核力求公平。要求各级管理人员及一线同志强化执行力,事不做好需反思,加强沟通与统筹,确保各项工作扎实落地,周会结束。"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,747 @@
|
|||
const $ = (selector) => document.querySelector(selector);
|
||||
const $$ = (selector) => document.querySelectorAll(selector);
|
||||
|
||||
const state = {
|
||||
meetingId: null,
|
||||
meetings: [],
|
||||
templateName: "template1.md",
|
||||
editMode: false,
|
||||
processing: false,
|
||||
activeTab: "template",
|
||||
};
|
||||
|
||||
const STORAGE_KEY = "meeting-workspace-preferences";
|
||||
|
||||
function loadPreferences() {
|
||||
try {
|
||||
const raw = window.localStorage.getItem(STORAGE_KEY);
|
||||
return raw ? JSON.parse(raw) : {};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function savePreferences(partial) {
|
||||
const next = { ...loadPreferences(), ...partial };
|
||||
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
||||
}
|
||||
|
||||
function applySavedLayout() {
|
||||
const prefs = loadPreferences();
|
||||
const sidebar = document.getElementById("sidebar");
|
||||
const resultPanel = document.getElementById("result-panel");
|
||||
const templatePanel = document.getElementById("template-panel");
|
||||
|
||||
if (prefs.layout?.sidebarWidth) {
|
||||
sidebar.style.flexBasis = `${prefs.layout.sidebarWidth}px`;
|
||||
sidebar.style.flexGrow = "0";
|
||||
}
|
||||
|
||||
if (prefs.layout?.templateWidth) {
|
||||
templatePanel.style.flexBasis = `${prefs.layout.templateWidth}px`;
|
||||
templatePanel.style.flexGrow = "0";
|
||||
}
|
||||
|
||||
if (prefs.layout?.resultWidth) {
|
||||
resultPanel.style.flexBasis = `${prefs.layout.resultWidth}px`;
|
||||
resultPanel.style.flexGrow = "0";
|
||||
}
|
||||
|
||||
if (prefs.templateName) {
|
||||
state.templateName = prefs.templateName;
|
||||
}
|
||||
|
||||
if (prefs.activeTab === "template" || prefs.activeTab === "original") {
|
||||
state.activeTab = prefs.activeTab;
|
||||
}
|
||||
}
|
||||
|
||||
function persistLayout() {
|
||||
const sidebar = document.getElementById("sidebar");
|
||||
const resultPanel = document.getElementById("result-panel");
|
||||
const templatePanel = document.getElementById("template-panel");
|
||||
|
||||
savePreferences({
|
||||
layout: {
|
||||
sidebarWidth: Math.round(sidebar.getBoundingClientRect().width),
|
||||
resultWidth: Math.round(resultPanel.getBoundingClientRect().width),
|
||||
templateWidth: Math.round(templatePanel.getBoundingClientRect().width),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function activateTab(tabName) {
|
||||
state.activeTab = tabName;
|
||||
$$("#panel-tabs .tab").forEach((item) => {
|
||||
item.classList.toggle("active", item.dataset.tab === tabName);
|
||||
});
|
||||
|
||||
const showTemplate = tabName === "template";
|
||||
$("#template-tab").hidden = !showTemplate;
|
||||
$("#original-tab").hidden = showTemplate;
|
||||
|
||||
savePreferences({ activeTab: tabName });
|
||||
}
|
||||
|
||||
function toast(message, type = "ok") {
|
||||
const el = $("#toast");
|
||||
el.textContent = message;
|
||||
el.className = `toast ${type} show`;
|
||||
clearTimeout(el._timer);
|
||||
el._timer = setTimeout(() => el.classList.remove("show"), 2400);
|
||||
}
|
||||
|
||||
function openModal(id) {
|
||||
document.getElementById(id).classList.add("show");
|
||||
}
|
||||
|
||||
function closeModal(id) {
|
||||
document.getElementById(id).classList.remove("show");
|
||||
}
|
||||
|
||||
async function api(url, options) {
|
||||
const res = await fetch(url, options || {});
|
||||
if (!res.ok) {
|
||||
const detail = await res.json().catch(() => ({ detail: res.statusText }));
|
||||
throw new Error(detail.detail || "Request failed");
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
function meetingById(meetingId) {
|
||||
return state.meetings.find((item) => item.id === meetingId) || null;
|
||||
}
|
||||
|
||||
function renderMeetingStatus(meeting) {
|
||||
const name = $("#sidebar-meeting-name");
|
||||
const meta = $("#sidebar-meeting-meta");
|
||||
const tip = $("#selected-meeting-tip");
|
||||
const summaryBadge = $("#badge-summary");
|
||||
const topicsBadge = $("#badge-topics");
|
||||
|
||||
if (!meeting) {
|
||||
name.textContent = "当前会议:未选择";
|
||||
meta.textContent = "请从左侧选择一个会议开始处理。";
|
||||
tip.textContent = "未选择会议";
|
||||
summaryBadge.textContent = "未生成总结";
|
||||
topicsBadge.textContent = "未生成主题 JSON";
|
||||
summaryBadge.className = "badge muted";
|
||||
topicsBadge.className = "badge muted";
|
||||
return;
|
||||
}
|
||||
|
||||
name.textContent = `当前会议:${meeting.name}`;
|
||||
meta.textContent = `ID: ${meeting.id} · 导入时间:${meeting.created_at || "未知"} · 源文件:${meeting.original_filename || meeting.transcript_filename || "未知"}`;
|
||||
tip.textContent = `当前处理会议:${meeting.name} (${meeting.id})`;
|
||||
summaryBadge.textContent = meeting.has_summary ? "已生成总结" : "未生成总结";
|
||||
topicsBadge.textContent = meeting.has_topics ? "已生成主题 JSON" : "未生成主题 JSON";
|
||||
summaryBadge.className = meeting.has_summary ? "badge" : "badge muted";
|
||||
topicsBadge.className = meeting.has_topics ? "badge" : "badge muted";
|
||||
}
|
||||
|
||||
function resetProcessingStream() {
|
||||
$("#stream-box").style.display = "none";
|
||||
$("#stream-title").textContent = "";
|
||||
$("#stream-content").textContent = "";
|
||||
}
|
||||
|
||||
function showResult(markdown) {
|
||||
resetProcessingStream();
|
||||
$("#processing-indicator").hidden = true;
|
||||
$("#result-empty").hidden = true;
|
||||
const result = $("#result-md");
|
||||
result.style.display = "block";
|
||||
result.innerHTML = marked.parse(markdown);
|
||||
result.scrollTop = 0;
|
||||
}
|
||||
|
||||
function showProcessingView() {
|
||||
$("#result-empty").hidden = true;
|
||||
$("#result-md").style.display = "none";
|
||||
$("#processing-indicator").hidden = false;
|
||||
}
|
||||
|
||||
function showEmpty() {
|
||||
resetProcessingStream();
|
||||
$("#processing-indicator").hidden = true;
|
||||
$("#result-md").style.display = "none";
|
||||
$("#result-empty").hidden = false;
|
||||
}
|
||||
|
||||
function showResultPanel() {
|
||||
resetProcessingStream();
|
||||
$("#result-empty").hidden = true;
|
||||
$("#processing-indicator").hidden = true;
|
||||
$("#result-md").style.display = "none";
|
||||
}
|
||||
|
||||
function toDisplayContent(filename, content) {
|
||||
if (filename.endsWith(".json")) {
|
||||
try {
|
||||
return `\`\`\`json\n${JSON.stringify(JSON.parse(content), null, 2)}\n\`\`\``;
|
||||
} catch {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
if (filename.endsWith(".txt")) {
|
||||
return `\`\`\`\n${content}\n\`\`\``;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
async function setCurrentMeeting(meetingId) {
|
||||
const data = await api("/api/current-meeting", {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ meeting_id: meetingId }),
|
||||
});
|
||||
state.meetingId = data.active_meeting_id;
|
||||
renderMeetingStatus(data.meeting);
|
||||
$("#btn-process").disabled = !state.meetingId || state.processing;
|
||||
highlightSelectedMeeting();
|
||||
}
|
||||
|
||||
function highlightSelectedMeeting() {
|
||||
$$(".tree-row").forEach((row) => {
|
||||
const isCurrent = row.dataset.meetingId === state.meetingId;
|
||||
row.classList.toggle("selected", isCurrent);
|
||||
row.classList.toggle("active-meeting", isCurrent);
|
||||
});
|
||||
}
|
||||
|
||||
function renderNode(node, parent, depth) {
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.className = "tree-node";
|
||||
|
||||
const row = document.createElement("div");
|
||||
row.className = "tree-row";
|
||||
row.style.paddingLeft = `${10 + depth * 18}px`;
|
||||
|
||||
if (node.type === "folder") {
|
||||
const arrow = document.createElement("span");
|
||||
arrow.className = `arrow ${node.children?.length ? "" : "none"}`;
|
||||
arrow.textContent = "▶";
|
||||
row.appendChild(arrow);
|
||||
|
||||
const icon = document.createElement("span");
|
||||
icon.className = "icon";
|
||||
icon.textContent = node.id ? "🗂" : "📁";
|
||||
row.appendChild(icon);
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.className = "label";
|
||||
label.textContent = node.name;
|
||||
row.appendChild(label);
|
||||
|
||||
if (node.active) {
|
||||
const pin = document.createElement("span");
|
||||
pin.className = "meeting-pin";
|
||||
pin.textContent = "当前";
|
||||
row.appendChild(pin);
|
||||
}
|
||||
|
||||
if (node.id) {
|
||||
row.dataset.meetingId = node.id;
|
||||
const del = document.createElement("span");
|
||||
del.className = "del-btn";
|
||||
del.textContent = "删除";
|
||||
del.addEventListener("click", async (event) => {
|
||||
event.stopPropagation();
|
||||
await deleteMeetingNode(node.id, node.delete_mode || "meeting");
|
||||
});
|
||||
row.appendChild(del);
|
||||
}
|
||||
|
||||
row.addEventListener("click", async () => {
|
||||
const children = wrapper.querySelector(":scope > .tree-children");
|
||||
if (children) {
|
||||
const isOpen = !children.classList.contains("open");
|
||||
children.classList.toggle("open", isOpen);
|
||||
arrow.classList.toggle("expanded", isOpen);
|
||||
}
|
||||
if (node.id) {
|
||||
await selectMeeting(node.id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const spacer = document.createElement("span");
|
||||
spacer.className = "arrow none";
|
||||
row.appendChild(spacer);
|
||||
|
||||
const icon = document.createElement("span");
|
||||
icon.className = "icon";
|
||||
if (node.name.endsWith(".md")) {
|
||||
icon.textContent = "📝";
|
||||
} else if (node.name.endsWith(".json")) {
|
||||
icon.textContent = "🔎";
|
||||
} else {
|
||||
icon.textContent = "📄";
|
||||
}
|
||||
row.appendChild(icon);
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.className = "label";
|
||||
label.textContent = node.name;
|
||||
row.appendChild(label);
|
||||
|
||||
row.addEventListener("click", async () => {
|
||||
if (!node.path) {
|
||||
return;
|
||||
}
|
||||
const parts = node.path.replace(/^(meetings|results_md|results_json)\//, "").split("/");
|
||||
const meetingId = parts[0];
|
||||
const filename = parts.slice(1).join("/");
|
||||
await setCurrentMeeting(meetingId);
|
||||
await viewMeetingFile(meetingId, filename);
|
||||
});
|
||||
}
|
||||
|
||||
wrapper.appendChild(row);
|
||||
|
||||
if (node.children?.length) {
|
||||
const children = document.createElement("div");
|
||||
children.className = `tree-children ${node.active ? "open" : ""}`;
|
||||
if (node.active) {
|
||||
row.querySelector(".arrow")?.classList.add("expanded");
|
||||
}
|
||||
node.children.forEach((child) => renderNode(child, children, depth + 1));
|
||||
wrapper.appendChild(children);
|
||||
}
|
||||
|
||||
parent.appendChild(wrapper);
|
||||
}
|
||||
|
||||
function buildTree(tree) {
|
||||
const root = $("#file-tree");
|
||||
root.innerHTML = "";
|
||||
(tree.children || []).forEach((child) => renderNode(child, root, 0));
|
||||
highlightSelectedMeeting();
|
||||
}
|
||||
|
||||
async function loadTree() {
|
||||
const tree = await api("/api/tree");
|
||||
buildTree(tree);
|
||||
}
|
||||
|
||||
async function selectMeeting(meetingId) {
|
||||
if (state.processing) {
|
||||
return;
|
||||
}
|
||||
await setCurrentMeeting(meetingId);
|
||||
showResultPanel();
|
||||
|
||||
try {
|
||||
const result = await api(`/api/meetings/${meetingId}/file/meeting_summary.md`);
|
||||
showResult(result.content);
|
||||
} catch {
|
||||
showEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
async function viewMeetingFile(meetingId, filename) {
|
||||
if (state.processing) {
|
||||
return;
|
||||
}
|
||||
const result = await api(`/api/meetings/${meetingId}/file/${encodeURIComponent(filename)}`);
|
||||
showResult(toDisplayContent(filename, result.content));
|
||||
}
|
||||
|
||||
async function deleteMeetingNode(meetingId, deleteMode) {
|
||||
const isDeleteMeeting = deleteMode === "meeting";
|
||||
const confirmMessage = isDeleteMeeting
|
||||
? "确定删除该会议原文及其全部处理结果吗?"
|
||||
: "确定只删除该会议的处理结果吗?原文将保留。";
|
||||
|
||||
if (!window.confirm(confirmMessage)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const endpoint = isDeleteMeeting
|
||||
? `/api/meetings/${meetingId}`
|
||||
: `/api/meetings/${meetingId}/results`;
|
||||
|
||||
await api(endpoint, { method: "DELETE" });
|
||||
toast(isDeleteMeeting ? "会议及处理结果已删除" : "处理结果已删除,原文已保留");
|
||||
await refresh();
|
||||
|
||||
if (isDeleteMeeting && !meetingById(state.meetingId)) {
|
||||
showEmpty();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDeleteMeeting && state.meetingId === meetingId) {
|
||||
try {
|
||||
const result = await api(`/api/meetings/${meetingId}/file/meeting_summary.md`);
|
||||
showResult(result.content);
|
||||
} catch {
|
||||
showEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateTemplatePreview(content) {
|
||||
const preview = $("#template-preview");
|
||||
preview.style.display = "block";
|
||||
preview.innerHTML = marked.parse(content);
|
||||
}
|
||||
|
||||
async function loadTemplate(name) {
|
||||
state.templateName = name;
|
||||
savePreferences({ templateName: name });
|
||||
const data = await api(`/api/templates/${name}`);
|
||||
state.editMode = false;
|
||||
$("#template-editor").value = data.content;
|
||||
$("#template-editor").style.display = "none";
|
||||
$("#template-preview").style.display = "block";
|
||||
updateTemplatePreview(data.content);
|
||||
$("#btn-toggle-edit").textContent = "编辑模板";
|
||||
$("#tpl-select").value = name;
|
||||
}
|
||||
|
||||
async function loadOriginalContent(meetingId) {
|
||||
const originalText = $("#original-content");
|
||||
const originalMarkdown = $("#original-markdown");
|
||||
|
||||
if (!meetingId) {
|
||||
originalMarkdown.hidden = true;
|
||||
originalMarkdown.style.display = "none";
|
||||
originalText.hidden = false;
|
||||
originalText.textContent = "未选择会议";
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const data = await api(`/api/meetings/${meetingId}/transcript`);
|
||||
const filename = (data.filename || "").toLowerCase();
|
||||
if (filename.endsWith(".md")) {
|
||||
originalText.hidden = true;
|
||||
originalMarkdown.hidden = false;
|
||||
originalMarkdown.style.display = "block";
|
||||
originalMarkdown.innerHTML = marked.parse(data.content);
|
||||
originalMarkdown.scrollTop = 0;
|
||||
} else {
|
||||
originalMarkdown.hidden = true;
|
||||
originalMarkdown.style.display = "none";
|
||||
originalText.hidden = false;
|
||||
originalText.textContent = data.content;
|
||||
originalText.scrollTop = 0;
|
||||
}
|
||||
} catch {
|
||||
originalMarkdown.hidden = true;
|
||||
originalMarkdown.style.display = "none";
|
||||
originalText.hidden = false;
|
||||
originalText.textContent = "无法加载当前会议原文";
|
||||
}
|
||||
}
|
||||
|
||||
function initResize(gutterId, leftId, rightId) {
|
||||
const gutter = document.getElementById(gutterId);
|
||||
const left = document.getElementById(leftId);
|
||||
const right = document.getElementById(rightId);
|
||||
let dragging = false;
|
||||
let startX = 0;
|
||||
let startLeftW = 0;
|
||||
let startRightW = 0;
|
||||
|
||||
gutter.addEventListener("mousedown", (event) => {
|
||||
if (window.innerWidth <= 1100) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
dragging = true;
|
||||
gutter.classList.add("dragging");
|
||||
startX = event.clientX;
|
||||
startLeftW = left.getBoundingClientRect().width;
|
||||
startRightW = right.getBoundingClientRect().width;
|
||||
document.body.style.cursor = "col-resize";
|
||||
document.body.style.userSelect = "none";
|
||||
});
|
||||
|
||||
document.addEventListener("mousemove", (event) => {
|
||||
if (!dragging) {
|
||||
return;
|
||||
}
|
||||
const dx = event.clientX - startX;
|
||||
const minLeft = Number(left.dataset.minWidth || 220);
|
||||
const minRight = Number(right.dataset.minWidth || 320);
|
||||
let nextLeft = Math.max(minLeft, startLeftW + dx);
|
||||
let nextRight = startRightW - dx;
|
||||
|
||||
if (nextRight < minRight) {
|
||||
nextRight = minRight;
|
||||
nextLeft = startLeftW + startRightW - minRight;
|
||||
}
|
||||
|
||||
if (leftId === "sidebar") {
|
||||
left.style.flexBasis = `${nextLeft}px`;
|
||||
left.style.flexGrow = "0";
|
||||
} else {
|
||||
left.style.flexBasis = "0%";
|
||||
left.style.flexGrow = "1";
|
||||
}
|
||||
|
||||
right.style.flexBasis = `${nextRight}px`;
|
||||
right.style.flexGrow = "0";
|
||||
});
|
||||
|
||||
document.addEventListener("mouseup", () => {
|
||||
if (!dragging) {
|
||||
return;
|
||||
}
|
||||
dragging = false;
|
||||
gutter.classList.remove("dragging");
|
||||
document.body.style.cursor = "";
|
||||
document.body.style.userSelect = "";
|
||||
persistLayout();
|
||||
});
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
const templateData = await api("/api/templates");
|
||||
const select = $("#tpl-select");
|
||||
select.innerHTML = "";
|
||||
templateData.forEach((item) => {
|
||||
const option = document.createElement("option");
|
||||
option.value = item.name;
|
||||
option.textContent = item.name;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
if (!templateData.some((item) => item.name === state.templateName) && templateData[0]) {
|
||||
state.templateName = templateData[0].name;
|
||||
}
|
||||
|
||||
const meetingsData = await api("/api/meetings");
|
||||
state.meetings = meetingsData.meetings || [];
|
||||
state.meetingId = meetingsData.active_meeting_id || null;
|
||||
|
||||
await loadTree();
|
||||
await loadTemplate(state.templateName);
|
||||
|
||||
const current = meetingById(state.meetingId);
|
||||
renderMeetingStatus(current);
|
||||
$("#btn-process").disabled = !state.meetingId || state.processing;
|
||||
|
||||
if (current) {
|
||||
try {
|
||||
const result = await api(`/api/meetings/${current.id}/file/meeting_summary.md`);
|
||||
showResult(result.content);
|
||||
} catch {
|
||||
showEmpty();
|
||||
}
|
||||
} else {
|
||||
showEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
$("#btn-process").addEventListener("click", () => {
|
||||
if (!state.meetingId || state.processing) {
|
||||
return;
|
||||
}
|
||||
|
||||
state.processing = true;
|
||||
$("#btn-process").disabled = true;
|
||||
showProcessingView();
|
||||
$("#stream-box").style.display = "block";
|
||||
$("#stream-title").textContent = "第一阶段:结构化主题...";
|
||||
$("#stream-content").textContent = "";
|
||||
|
||||
const source = new EventSource(
|
||||
`/api/meetings/${state.meetingId}/process?template_name=${encodeURIComponent(state.templateName)}`,
|
||||
);
|
||||
|
||||
let resultAcc = "";
|
||||
let streamAcc = "";
|
||||
|
||||
source.onmessage = async (event) => {
|
||||
if (!event.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = JSON.parse(event.data);
|
||||
|
||||
if (payload.type === "status") {
|
||||
if (payload.data === "preprocessing") {
|
||||
$("#stream-title").textContent = "第一阶段:结构化主题...";
|
||||
streamAcc = "";
|
||||
} else if (payload.data === "preprocessing_done") {
|
||||
$("#stream-title").textContent = "主题提取完成,开始生成会议总结...";
|
||||
} else if (payload.data === "summarizing") {
|
||||
$("#stream-title").textContent = "第二阶段:生成会议总结...";
|
||||
streamAcc = "";
|
||||
$("#stream-content").textContent = "";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload.type === "chunk") {
|
||||
const { data } = payload;
|
||||
streamAcc += data.text || "";
|
||||
$("#stream-content").textContent = streamAcc.replace(/\r\n/g, "\n").split("\n").slice(-4).join("\n");
|
||||
if (data.stage === 2 && data.chunk_type === "content") {
|
||||
resultAcc += data.text || "";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload.type === "done") {
|
||||
source.close();
|
||||
state.processing = false;
|
||||
$("#btn-process").disabled = false;
|
||||
showResult(payload.data?.result || resultAcc || "");
|
||||
await refresh();
|
||||
toast("会议处理完成");
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload.type === "error") {
|
||||
source.close();
|
||||
state.processing = false;
|
||||
$("#btn-process").disabled = false;
|
||||
resetProcessingStream();
|
||||
$("#processing-indicator").hidden = true;
|
||||
toast(`处理失败:${payload.data}`, "err");
|
||||
}
|
||||
};
|
||||
|
||||
source.onerror = () => {
|
||||
source.close();
|
||||
state.processing = false;
|
||||
$("#btn-process").disabled = false;
|
||||
resetProcessingStream();
|
||||
$("#processing-indicator").hidden = true;
|
||||
toast("处理连接中断", "err");
|
||||
};
|
||||
});
|
||||
|
||||
$("#btn-toggle-edit").addEventListener("click", async () => {
|
||||
state.editMode = !state.editMode;
|
||||
if (state.editMode) {
|
||||
$("#template-editor").style.display = "block";
|
||||
$("#template-preview").style.display = "none";
|
||||
$("#btn-toggle-edit").textContent = "保存模板";
|
||||
return;
|
||||
}
|
||||
|
||||
const content = $("#template-editor").value;
|
||||
$("#template-editor").style.display = "none";
|
||||
$("#template-preview").style.display = "block";
|
||||
$("#btn-toggle-edit").textContent = "编辑模板";
|
||||
updateTemplatePreview(content);
|
||||
|
||||
await api(`/api/templates/${state.templateName}`, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ content }),
|
||||
});
|
||||
toast("模板已保存");
|
||||
});
|
||||
|
||||
$("#tpl-select").addEventListener("change", async (event) => {
|
||||
await loadTemplate(event.target.value);
|
||||
});
|
||||
|
||||
$("#panel-tabs").addEventListener("click", async (event) => {
|
||||
const tab = event.target.closest(".tab");
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
activateTab(tab.dataset.tab);
|
||||
|
||||
if (tab.dataset.tab === "original") {
|
||||
await loadOriginalContent(state.meetingId);
|
||||
}
|
||||
});
|
||||
|
||||
$("#btn-import").addEventListener("click", () => {
|
||||
$("#import-name").value = "";
|
||||
$("#import-file").value = "";
|
||||
openModal("modal-import");
|
||||
});
|
||||
|
||||
$("#btn-confirm-import").addEventListener("click", async () => {
|
||||
const name = $("#import-name").value.trim();
|
||||
const file = $("#import-file").files[0];
|
||||
if (!name) {
|
||||
toast("请输入会议名称", "err");
|
||||
return;
|
||||
}
|
||||
if (!file) {
|
||||
toast("请选择转录文件", "err");
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("name", name);
|
||||
formData.append("file", file);
|
||||
|
||||
const result = await fetch("/api/meetings/import", { method: "POST", body: formData });
|
||||
if (!result.ok) {
|
||||
const detail = await result.json().catch(() => ({ detail: "Import failed" }));
|
||||
toast(`导入失败:${detail.detail}`, "err");
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = await result.json();
|
||||
closeModal("modal-import");
|
||||
toast(`导入成功:${name}`);
|
||||
await refresh();
|
||||
await selectMeeting(payload.id);
|
||||
});
|
||||
|
||||
$("#btn-settings").addEventListener("click", async () => {
|
||||
try {
|
||||
const cfg = await api("/api/settings");
|
||||
$("#cfg-url").value = cfg.api_base_url || "";
|
||||
$("#cfg-key").value = cfg.api_key || "";
|
||||
$("#cfg-model").value = cfg.model_name || "";
|
||||
} finally {
|
||||
openModal("modal-settings");
|
||||
}
|
||||
});
|
||||
|
||||
$("#btn-save-settings").addEventListener("click", async () => {
|
||||
const payload = {
|
||||
api_base_url: $("#cfg-url").value.trim(),
|
||||
api_key: $("#cfg-key").value.trim(),
|
||||
model_name: $("#cfg-model").value.trim(),
|
||||
};
|
||||
await api("/api/settings", {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
closeModal("modal-settings");
|
||||
toast("配置已保存");
|
||||
});
|
||||
|
||||
$$("[data-close]").forEach((button) => {
|
||||
button.addEventListener("click", () => closeModal(button.dataset.close));
|
||||
});
|
||||
|
||||
["modal-import", "modal-settings"].forEach((id) => {
|
||||
document.getElementById(id).addEventListener("click", (event) => {
|
||||
if (event.target.id === id) {
|
||||
closeModal(id);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
document.getElementById("sidebar").dataset.minWidth = "260";
|
||||
document.getElementById("result-panel").dataset.minWidth = "360";
|
||||
document.getElementById("template-panel").dataset.minWidth = "360";
|
||||
|
||||
applySavedLayout();
|
||||
initResize("gutter-1", "sidebar", "result-panel");
|
||||
initResize("gutter-2", "result-panel", "template-panel");
|
||||
|
||||
try {
|
||||
await refresh();
|
||||
activateTab(state.activeTab);
|
||||
if (state.activeTab === "original") {
|
||||
await loadOriginalContent(state.meetingId);
|
||||
}
|
||||
} catch (error) {
|
||||
toast(error.message, "err");
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,717 @@
|
|||
:root {
|
||||
--bg: #eef5ff;
|
||||
--bg-2: #dbeafe;
|
||||
--panel: rgba(255, 255, 255, 0.94);
|
||||
--panel-strong: #ffffff;
|
||||
--line: #c7dcf8;
|
||||
--line-strong: #9cc3f5;
|
||||
--text: #16324f;
|
||||
--muted: #5f7f9f;
|
||||
--accent: #2f80ed;
|
||||
--accent-strong: #1c63c7;
|
||||
--accent-soft: #e8f2ff;
|
||||
--ok-bg: #e9f7f1;
|
||||
--ok-text: #19744e;
|
||||
--danger-bg: #fdecec;
|
||||
--danger-text: #b53f4e;
|
||||
--shadow: 0 18px 48px rgba(47, 128, 237, 0.12);
|
||||
--radius: 18px;
|
||||
--font: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
--mono: "Cascadia Code", "JetBrains Mono", Consolas, monospace;
|
||||
--app-h: 100vh;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font);
|
||||
color: var(--text);
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(47, 128, 237, 0.18), transparent 30%),
|
||||
linear-gradient(180deg, #f6fbff 0%, var(--bg) 54%, var(--bg-2) 100%);
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.app-shell {
|
||||
height: var(--app-h);
|
||||
padding: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.topbar,
|
||||
.panel,
|
||||
.modal-box,
|
||||
.toast {
|
||||
backdrop-filter: blur(16px);
|
||||
}
|
||||
|
||||
.topbar,
|
||||
.panel {
|
||||
background: var(--panel);
|
||||
border: 1px solid rgba(156, 195, 245, 0.75);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.topbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px 24px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0 0 8px;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.18em;
|
||||
color: var(--accent-strong);
|
||||
}
|
||||
|
||||
.topbar h1 {
|
||||
margin: 0;
|
||||
font-size: 28px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.topbar-actions,
|
||||
.toolbar,
|
||||
.modal-actions,
|
||||
.header-badges {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.workspace {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
gap: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel {
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
flex: 0 0 330px;
|
||||
min-width: 260px;
|
||||
}
|
||||
|
||||
#result-panel {
|
||||
flex: 1 1 auto;
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
#template-panel {
|
||||
flex: 0 0 42%;
|
||||
min-width: 360px;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: 14px;
|
||||
padding: 16px 18px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(244, 249, 255, 0.92));
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.panel-heading span {
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.panel-heading small {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
color: var(--muted);
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
.header-badges {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel-scroll,
|
||||
.tree,
|
||||
#template-tab,
|
||||
#original-tab {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.tree,
|
||||
#result-body,
|
||||
#template-body,
|
||||
#template-editor,
|
||||
#template-preview,
|
||||
#original-content,
|
||||
#result-md {
|
||||
overflow: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #8bb8f1 rgba(232, 242, 255, 0.7);
|
||||
}
|
||||
|
||||
.tree::-webkit-scrollbar,
|
||||
#result-body::-webkit-scrollbar,
|
||||
#template-body::-webkit-scrollbar,
|
||||
#template-editor::-webkit-scrollbar,
|
||||
#template-preview::-webkit-scrollbar,
|
||||
#original-content::-webkit-scrollbar,
|
||||
#result-md::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.tree::-webkit-scrollbar-track,
|
||||
#result-body::-webkit-scrollbar-track,
|
||||
#template-body::-webkit-scrollbar-track,
|
||||
#template-editor::-webkit-scrollbar-track,
|
||||
#template-preview::-webkit-scrollbar-track,
|
||||
#original-content::-webkit-scrollbar-track,
|
||||
#result-md::-webkit-scrollbar-track {
|
||||
background: rgba(232, 242, 255, 0.8);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.tree::-webkit-scrollbar-thumb,
|
||||
#result-body::-webkit-scrollbar-thumb,
|
||||
#template-body::-webkit-scrollbar-thumb,
|
||||
#template-editor::-webkit-scrollbar-thumb,
|
||||
#template-preview::-webkit-scrollbar-thumb,
|
||||
#original-content::-webkit-scrollbar-thumb,
|
||||
#result-md::-webkit-scrollbar-thumb {
|
||||
background: linear-gradient(180deg, #8bb8f1, #4f93eb);
|
||||
border-radius: 999px;
|
||||
border: 2px solid rgba(232, 242, 255, 0.8);
|
||||
}
|
||||
|
||||
.gutter {
|
||||
width: 10px;
|
||||
position: relative;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.gutter::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 18px 3px;
|
||||
border-radius: 999px;
|
||||
background: rgba(47, 128, 237, 0.18);
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
|
||||
.gutter:hover::before,
|
||||
.gutter.dragging::before {
|
||||
background: rgba(47, 128, 237, 0.44);
|
||||
}
|
||||
|
||||
.btn {
|
||||
height: 36px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
background: var(--panel-strong);
|
||||
color: var(--text);
|
||||
padding: 0 14px;
|
||||
cursor: pointer;
|
||||
transition: 0.15s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: var(--accent);
|
||||
color: var(--accent-strong);
|
||||
}
|
||||
|
||||
.btn.primary {
|
||||
color: #fff;
|
||||
border-color: transparent;
|
||||
background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
|
||||
}
|
||||
|
||||
.btn.primary:hover {
|
||||
filter: brightness(1.03);
|
||||
}
|
||||
|
||||
.btn.sm {
|
||||
height: 34px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
select.btn {
|
||||
min-width: 132px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 7px 12px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.badge {
|
||||
background: var(--ok-bg);
|
||||
color: var(--ok-text);
|
||||
border-color: rgba(25, 116, 78, 0.12);
|
||||
}
|
||||
|
||||
.badge.muted {
|
||||
background: var(--accent-soft);
|
||||
color: var(--accent-strong);
|
||||
border-color: rgba(47, 128, 237, 0.18);
|
||||
}
|
||||
|
||||
.tree {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.tree-node + .tree-node {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tree-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-height: 36px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tree-row:hover {
|
||||
background: rgba(47, 128, 237, 0.08);
|
||||
}
|
||||
|
||||
.tree-row.selected {
|
||||
background: linear-gradient(135deg, rgba(47, 128, 237, 0.16), rgba(47, 128, 237, 0.06));
|
||||
}
|
||||
|
||||
.tree-row.active-meeting {
|
||||
outline: 1px solid rgba(47, 128, 237, 0.28);
|
||||
}
|
||||
|
||||
.tree-row .arrow,
|
||||
.tree-row .icon,
|
||||
.tree-row .del-btn,
|
||||
.meeting-pin {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.tree-row .arrow {
|
||||
width: 14px;
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
transition: transform 0.1s ease;
|
||||
}
|
||||
|
||||
.tree-row .arrow.expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.tree-row .arrow.none {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.tree-row .label {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tree-row .del-btn,
|
||||
.meeting-pin {
|
||||
color: var(--muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.tree-row .del-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tree-row:hover .del-btn {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.tree-children {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tree-children.open {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.empty-state,
|
||||
.processing {
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: var(--muted);
|
||||
padding: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 24px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
margin: 0 auto 14px;
|
||||
color: var(--accent-strong);
|
||||
background: linear-gradient(135deg, rgba(47, 128, 237, 0.16), rgba(47, 128, 237, 0.05));
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border: 3px solid rgba(47, 128, 237, 0.16);
|
||||
border-top-color: var(--accent);
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.stream-box {
|
||||
position: relative;
|
||||
width: min(620px, calc(100% - 40px));
|
||||
background: rgba(248, 252, 255, 0.98);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 18px;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
box-shadow: 0 14px 36px rgba(47, 128, 237, 0.1);
|
||||
}
|
||||
|
||||
.stream-box::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -35%;
|
||||
width: 35%;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, rgba(47, 128, 237, 0), rgba(47, 128, 237, 0.95), rgba(47, 128, 237, 0));
|
||||
animation: marquee-glow 1.8s linear infinite;
|
||||
}
|
||||
|
||||
.stream-title {
|
||||
position: relative;
|
||||
padding: 12px 16px 10px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
font-weight: 700;
|
||||
color: var(--accent-strong);
|
||||
background: linear-gradient(180deg, rgba(232, 242, 255, 0.92), rgba(248, 252, 255, 0.98));
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.stream-title::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(47, 128, 237, 0) 0%,
|
||||
rgba(125, 182, 255, 0.12) 16%,
|
||||
rgba(125, 182, 255, 0.28) 38%,
|
||||
rgba(125, 182, 255, 0.36) 50%,
|
||||
rgba(125, 182, 255, 0.28) 62%,
|
||||
rgba(125, 182, 255, 0.12) 84%,
|
||||
rgba(47, 128, 237, 0) 100%
|
||||
);
|
||||
transform: none;
|
||||
animation: title-marquee 2.2s linear infinite;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.stream-content,
|
||||
#original-content,
|
||||
#template-editor {
|
||||
font-family: var(--mono);
|
||||
}
|
||||
|
||||
.stream-content {
|
||||
margin: 0;
|
||||
padding: 14px 16px 16px;
|
||||
white-space: pre-wrap;
|
||||
min-height: 116px;
|
||||
max-height: 220px;
|
||||
overflow: auto;
|
||||
color: #557cad;
|
||||
line-height: 1.45;
|
||||
background: rgba(251, 253, 255, 0.96);
|
||||
}
|
||||
|
||||
@keyframes marquee-glow {
|
||||
from {
|
||||
left: -35%;
|
||||
}
|
||||
to {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes title-marquee {
|
||||
0% {
|
||||
left: -100%;
|
||||
}
|
||||
62% {
|
||||
left: 100%;
|
||||
}
|
||||
100% {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#result-md,
|
||||
#template-preview,
|
||||
#original-markdown,
|
||||
#original-content {
|
||||
padding: 18px 20px;
|
||||
}
|
||||
|
||||
#result-md,
|
||||
#template-preview,
|
||||
#original-markdown {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#template-editor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
padding: 18px 20px;
|
||||
background: transparent;
|
||||
resize: none;
|
||||
outline: none;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#original-content {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.panel-tabs {
|
||||
display: inline-flex;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
background: rgba(232, 242, 255, 0.55);
|
||||
}
|
||||
|
||||
.tab {
|
||||
min-height: 34px;
|
||||
padding: 0 14px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
background: rgba(47, 128, 237, 0.15);
|
||||
color: var(--accent-strong);
|
||||
}
|
||||
|
||||
.md-content {
|
||||
line-height: 1.8;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.md-content h1,
|
||||
.md-content h2,
|
||||
.md-content h3 {
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.md-content code {
|
||||
background: rgba(47, 128, 237, 0.08);
|
||||
padding: 2px 6px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.md-content pre {
|
||||
padding: 14px;
|
||||
overflow: auto;
|
||||
border-radius: 14px;
|
||||
background: #12325e;
|
||||
color: #eef6ff;
|
||||
}
|
||||
|
||||
.md-content blockquote {
|
||||
margin: 0;
|
||||
padding-left: 14px;
|
||||
border-left: 3px solid var(--accent);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: none;
|
||||
place-items: center;
|
||||
background: rgba(17, 47, 84, 0.28);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.modal-mask.show {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.modal-box {
|
||||
width: min(480px, 100%);
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
border: 1px solid rgba(156, 195, 245, 0.8);
|
||||
border-radius: 22px;
|
||||
padding: 22px;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.modal-box h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
display: block;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.form-field span {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
color: var(--muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.form-field input {
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
background: #f9fcff;
|
||||
}
|
||||
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 22px;
|
||||
right: 22px;
|
||||
max-width: 360px;
|
||||
padding: 12px 16px;
|
||||
border-radius: 14px;
|
||||
color: #fff;
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
pointer-events: none;
|
||||
transition: 0.18s ease;
|
||||
background: rgba(28, 99, 199, 0.96);
|
||||
}
|
||||
|
||||
.toast.err {
|
||||
background: rgba(181, 63, 78, 0.95);
|
||||
}
|
||||
|
||||
.toast.show {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
html,
|
||||
body {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.app-shell {
|
||||
height: auto;
|
||||
min-height: 100vh;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.workspace {
|
||||
flex-direction: column;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
#sidebar,
|
||||
#result-panel,
|
||||
#template-panel {
|
||||
flex-basis: auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel {
|
||||
min-height: 360px;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Meeting Summary</title>
|
||||
<link rel="stylesheet" href="/assets/styles.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/13.0.3/marked.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<header class="topbar">
|
||||
<div>
|
||||
<p class="eyebrow">FRONTEND + BACKEND</p>
|
||||
<h1>Meeting Summary Workspace</h1>
|
||||
</div>
|
||||
<div class="topbar-actions">
|
||||
<button class="btn primary" id="btn-import">导入会议</button>
|
||||
<button class="btn" id="btn-settings">设置</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="workspace" id="main-container">
|
||||
<aside class="panel" id="sidebar">
|
||||
<div class="panel-header sidebar-header">
|
||||
<div class="panel-heading">
|
||||
<span>会议资源</span>
|
||||
<small id="sidebar-meeting-name">当前会议:未选择</small>
|
||||
<small id="sidebar-meeting-meta">请从左侧选择一个会议开始处理。</small>
|
||||
</div>
|
||||
<div class="header-badges">
|
||||
<span class="badge muted" id="badge-summary">未生成总结</span>
|
||||
<span class="badge muted" id="badge-topics">未生成主题 JSON</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="tree" id="file-tree"></div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<div class="gutter" id="gutter-1"></div>
|
||||
|
||||
<section class="panel panel-main" id="result-panel">
|
||||
<div class="panel-header">
|
||||
<div class="panel-heading">
|
||||
<span>处理结果</span>
|
||||
<small id="selected-meeting-tip">未选择会议</small>
|
||||
</div>
|
||||
<button class="btn primary sm" id="btn-process" disabled>处理当前会议</button>
|
||||
</div>
|
||||
<div class="panel-body panel-scroll" id="result-body">
|
||||
<div id="result-empty" class="empty-state">
|
||||
<div class="empty-icon">M</div>
|
||||
<p>选择会议后即可查看结果,或直接开始处理。</p>
|
||||
</div>
|
||||
<div id="processing-indicator" class="processing" hidden>
|
||||
<div class="stream-box" id="stream-box">
|
||||
<div class="stream-title" id="stream-title"></div>
|
||||
<pre class="stream-content" id="stream-content"></pre>
|
||||
</div>
|
||||
</div>
|
||||
<article id="result-md" class="md-content"></article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="gutter" id="gutter-2"></div>
|
||||
|
||||
<section class="panel" id="template-panel">
|
||||
<div class="panel-header">
|
||||
<div class="panel-heading">
|
||||
<span>模板与原文</span>
|
||||
<small>每个分区独立滚动,页面整体固定</small>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<div class="panel-tabs" id="panel-tabs">
|
||||
<button class="tab active" data-tab="template">模板</button>
|
||||
<button class="tab" data-tab="original">原文</button>
|
||||
</div>
|
||||
<select class="btn sm" id="tpl-select"></select>
|
||||
<button class="btn sm" id="btn-toggle-edit">编辑模板</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body panel-scroll" id="template-body">
|
||||
<section id="template-tab">
|
||||
<textarea id="template-editor" spellcheck="false"></textarea>
|
||||
<article id="template-preview" class="md-content"></article>
|
||||
</section>
|
||||
<section id="original-tab" hidden>
|
||||
<article id="original-markdown" class="md-content" hidden></article>
|
||||
<pre id="original-content"></pre>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<div class="modal-mask" id="modal-import">
|
||||
<div class="modal-box">
|
||||
<h3>导入会议转录</h3>
|
||||
<label class="form-field">
|
||||
<span>会议名称</span>
|
||||
<input type="text" id="import-name" placeholder="例如:2026-05-08 周例会">
|
||||
</label>
|
||||
<label class="form-field">
|
||||
<span>转录文件(.txt / .md)</span>
|
||||
<input type="file" id="import-file" accept=".txt,.md">
|
||||
</label>
|
||||
<div class="modal-actions">
|
||||
<button class="btn" data-close="modal-import">取消</button>
|
||||
<button class="btn primary" id="btn-confirm-import">导入</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-mask" id="modal-settings">
|
||||
<div class="modal-box">
|
||||
<h3>API 配置</h3>
|
||||
<label class="form-field">
|
||||
<span>Base URL</span>
|
||||
<input type="text" id="cfg-url" placeholder="http://host:port/v1">
|
||||
</label>
|
||||
<label class="form-field">
|
||||
<span>API Key</span>
|
||||
<input type="text" id="cfg-key" placeholder="your-api-key">
|
||||
</label>
|
||||
<label class="form-field">
|
||||
<span>Model Name</span>
|
||||
<input type="text" id="cfg-model" placeholder="Qwen3.6-35B">
|
||||
</label>
|
||||
<div class="modal-actions">
|
||||
<button class="btn" data-close="modal-settings">取消</button>
|
||||
<button class="btn primary" id="btn-save-settings">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toast" id="toast"></div>
|
||||
<script type="module" src="/assets/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
import argparse
|
||||
import json
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from agents.chat import get_qwen_response
|
||||
from prompt_loader import load_prompt
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent
|
||||
DATA_DIR = PROJECT_ROOT / "data" / "meetings"
|
||||
RESULTS_MD_DIR = PROJECT_ROOT / "data" / "results" / "md"
|
||||
RESULTS_JSON_DIR = PROJECT_ROOT / "data" / "results" / "json"
|
||||
TEMPLATE_DIR = PROJECT_ROOT / "template"
|
||||
EXAMPLES_DIR = PROJECT_ROOT / "examples"
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Generate meeting topics and summary.")
|
||||
parser.add_argument("--meeting-id", help="Meeting ID under data/meetings")
|
||||
parser.add_argument("--input", help="Path to a transcript file (.txt or .md)")
|
||||
parser.add_argument("--template", default="template1.md", help="Template file name under template/")
|
||||
parser.add_argument("--model", default="Qwen3.6-35B", help="LLM model name")
|
||||
args = parser.parse_args()
|
||||
|
||||
if bool(args.meeting_id) == bool(args.input):
|
||||
parser.error("Use exactly one of --meeting-id or --input")
|
||||
return args
|
||||
|
||||
|
||||
def load_transcript(args) -> tuple[str, str, Path]:
|
||||
if args.meeting_id:
|
||||
meeting_dir = DATA_DIR / args.meeting_id
|
||||
if not meeting_dir.exists():
|
||||
raise FileNotFoundError(f"Meeting not found: {args.meeting_id}")
|
||||
|
||||
for ext in (".txt", ".md"):
|
||||
transcript_path = meeting_dir / f"transcript{ext}"
|
||||
if transcript_path.exists():
|
||||
return args.meeting_id, transcript_path.read_text(encoding="utf-8"), transcript_path
|
||||
raise FileNotFoundError(f"No transcript file found for meeting: {args.meeting_id}")
|
||||
|
||||
transcript_path = Path(args.input).resolve()
|
||||
if not transcript_path.exists():
|
||||
raise FileNotFoundError(f"Input file not found: {transcript_path}")
|
||||
return transcript_path.stem, transcript_path.read_text(encoding="utf-8"), transcript_path
|
||||
|
||||
|
||||
def read_template(template_name: str) -> str:
|
||||
template_path = TEMPLATE_DIR / template_name
|
||||
if not template_path.exists():
|
||||
raise FileNotFoundError(f"Template not found: {template_name}")
|
||||
return template_path.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def collect_stream(response) -> str:
|
||||
content = []
|
||||
current_part = None
|
||||
|
||||
for chunk_type, chunk_content in response:
|
||||
if not chunk_content:
|
||||
continue
|
||||
|
||||
if chunk_type == "reasoning":
|
||||
if current_part != "reasoning":
|
||||
print("\n[Thinking]\n")
|
||||
current_part = "reasoning"
|
||||
print(chunk_content, end="", flush=True)
|
||||
else:
|
||||
if current_part != "content":
|
||||
print("\n[Content]\n")
|
||||
current_part = "content"
|
||||
print(chunk_content, end="", flush=True)
|
||||
content.append(str(chunk_content))
|
||||
|
||||
print()
|
||||
return "".join(content)
|
||||
|
||||
|
||||
def save_outputs(target_name: str, meeting_id: str | None, sub_topics: str, summary_text: str):
|
||||
if meeting_id:
|
||||
json_dir = RESULTS_JSON_DIR / meeting_id
|
||||
md_dir = RESULTS_MD_DIR / meeting_id
|
||||
else:
|
||||
json_dir = EXAMPLES_DIR
|
||||
md_dir = EXAMPLES_DIR
|
||||
|
||||
json_dir.mkdir(parents=True, exist_ok=True)
|
||||
md_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
json_path = json_dir / "sub_topic.json"
|
||||
try:
|
||||
json_path.write_text(
|
||||
json.dumps(json.loads(sub_topics), ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
except json.JSONDecodeError:
|
||||
json_path.write_text(sub_topics, encoding="utf-8")
|
||||
|
||||
summary_path = md_dir / "meeting_summary.md"
|
||||
summary_path.write_text(summary_text, encoding="utf-8")
|
||||
|
||||
print(f"\nSaved topics to: {json_path}")
|
||||
print(f"Saved summary to: {summary_path}")
|
||||
print(f"Processed target: {target_name}")
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
started_at = time.perf_counter()
|
||||
|
||||
target_name, transcript, transcript_path = load_transcript(args)
|
||||
template = read_template(args.template)
|
||||
prompt = load_prompt("meeting_summary", "zh")
|
||||
|
||||
print(f"Processing transcript: {transcript_path}")
|
||||
if args.meeting_id:
|
||||
print(f"Meeting ID: {args.meeting_id}")
|
||||
|
||||
system_prompt = prompt["system"]["role"] + prompt["mode_contracts"]["data_preproces"]
|
||||
user_prompt = prompt["user_template"]["article_preproces"].format(article=transcript)
|
||||
sub_topics = collect_stream(get_qwen_response(args.model, system_prompt, user_prompt))
|
||||
|
||||
system_prompt = prompt["system"]["role"] + prompt["mode_contracts"]["data_summary"].format(template=template)
|
||||
user_prompt = prompt["user_template"]["article_summary"].format(article=transcript, sub_topices=sub_topics)
|
||||
summary_text = collect_stream(get_qwen_response(args.model, system_prompt, user_prompt))
|
||||
|
||||
save_outputs(target_name, args.meeting_id, sub_topics, summary_text)
|
||||
|
||||
elapsed = time.perf_counter() - started_at
|
||||
print(f"Elapsed: {elapsed:.2f}s")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
system:
|
||||
role: |
|
||||
你是一名专业的会议纪要分析助手。你的任务是基于会议转录内容,输出结构清晰、信息准确、表达简洁的会议总结。
|
||||
你必须忠实于原始会议内容,不臆测、不补造、不为了凑结构而编写空泛内容。
|
||||
|
||||
mode_contracts:
|
||||
data_preproces: |
|
||||
你需要先按时间顺序拆分会议话题,而不是直接输出整篇总结。
|
||||
要求如下:
|
||||
- 找出会议中的主要话题段落,并为每个话题标注对应的时间区间。
|
||||
- 为每个话题生成一个贴合内容的标题。
|
||||
- 对每个话题写 2-3 句概览,概括主题、关键事项和关键数据。
|
||||
- 只输出最终 JSON,不输出解释、说明或额外文字。
|
||||
|
||||
data_summary: |
|
||||
请严格参考下方模板的“大结构和层级关系”输出会议总结,最终结果必须为 Markdown。
|
||||
|
||||
结构要求:
|
||||
- 保留模板中的一级/二级主结构,不要随意改写整体框架顺序。
|
||||
- 模板中的占位词、示例词、说明文字不能原样输出,必须替换或删除。
|
||||
- 会议实际没有涉及的“小节、子项、占位条目”可以直接省略,不要为了凑模板保留“无相关内容”“XXX”“待补充”等字样。
|
||||
- 如果某个一级模块完全没有可靠信息支撑,则该一级模块整体可以省略。
|
||||
- 如果某个模块下只有部分子项有内容,则只保留有内容的子项,不必把其他子项补齐。
|
||||
|
||||
内容要求:
|
||||
- 总结必须完全依据会议原文和话题拆分结果,不得杜撰。
|
||||
- 会议讨论方向每次都可能不同,标题、分组、关注点要根据本次会议内容动态生成,不能机械套用固定业务分类。
|
||||
- 保留会议中的关键数字、结论、动作、责任信息和明确判断。
|
||||
- 不要输出时间区间,不要把拆分话题中的时间标记带入最终纪要。
|
||||
- 保持中文表达自然、简洁、客观,避免空话套话。
|
||||
- 如果模板中的某个小标题与本次会议不完全匹配,可以在不破坏整体层级的前提下,改成更贴合本次会议内容的标题。
|
||||
|
||||
模板:
|
||||
{template}
|
||||
|
||||
user_template:
|
||||
article_preproces: |
|
||||
请基于下方会议原文,按照时间顺序拆分会议话题。
|
||||
只输出 JSON,不要输出任何额外说明。
|
||||
|
||||
会议原文:
|
||||
{article}
|
||||
|
||||
输出 JSON 格式:
|
||||
{{
|
||||
"sub_topics": [
|
||||
{{
|
||||
"title": "话题标题",
|
||||
"time_interval": "话题所在时间区间",
|
||||
"overview": "2-3句概览,概括该话题的主题、关键事项和关键数据"
|
||||
}}
|
||||
]
|
||||
}}
|
||||
|
||||
article_summary: |
|
||||
请参考拆分话题结果,对会议原文进行结构化总结。
|
||||
|
||||
会议原文:
|
||||
{article}
|
||||
|
||||
话题拆分结果:
|
||||
{sub_topices}
|
||||
|
||||
输出要求:
|
||||
- 严格遵循模板的大结构,但不要机械保留无意义占位内容
|
||||
- 模板中没有被会议内容支撑的小节、子项、占位条目,直接删除,不要输出“无相关内容”
|
||||
- 每次会议讨论方向都可能不同,需根据本次会议实际内容动态组织主题和小标题
|
||||
- 只保留有明确信息依据的内容,避免泛化扩写
|
||||
- 重点保留关键数据、问题、决策、动作、责任分工和后续安排
|
||||
- 语言保持客观、准确、简洁
|
||||
- 按会议实际讨论顺序组织内容,但不要照搬时间区间
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import yaml
|
||||
|
||||
PROMPT_ROOT = Path(__file__).resolve().parent / "prompt"
|
||||
|
||||
def load_prompt(agent_name: str, language: str = "zh") -> dict[str, Any]:
|
||||
lang = "zh" if language.lower().startswith("zh") else "zh"
|
||||
path = PROMPT_ROOT / lang / f"{agent_name}.yaml"
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"Prompt file not found: {path}")
|
||||
with path.open("r", encoding="utf-8") as f:
|
||||
data = yaml.safe_load(f) or {}
|
||||
if not isinstance(data, dict):
|
||||
raise ValueError(f"Prompt file must contain a YAML object: {path}")
|
||||
return data
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
openai
|
||||
pyyaml
|
||||
fastapi
|
||||
uvicorn
|
||||
python-multipart
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
## 📝 会议概述
|
||||
[简述产品开发背景、当前阶段、主要议题和预期交付成果]
|
||||
|
||||
## 🚀 核心议题
|
||||
|
||||
### 议题1:[主题标题]
|
||||
- 需求分析: [用户需求、市场需求、功能需求定义与优先级]
|
||||
- 技术评估: [技术可行性、架构选择、开发难度评估]
|
||||
- 资源规划: [人力配置、时间安排、预算分配]
|
||||
|
||||
### 议题2:[主题标题]
|
||||
- 设计方案: [产品设计、UI/UX设计、交互逻辑设计]
|
||||
- 原型验证: [原型测试结果、用户反馈、迭代方向]
|
||||
- 标准制定: [开发规范、质量标准、验收标准]
|
||||
|
||||
### 议题3:[主题标题]
|
||||
- 开发进度: [当前开发状态、里程碑达成、延期风险]
|
||||
- 技术难点: [技术挑战、解决方案、备选方案]
|
||||
- 测试策略: [测试计划、测试用例、Bug修复优先级]
|
||||
|
||||
## ❓ 关键问答
|
||||
|
||||
Q: [技术实现问题1]
|
||||
A: [技术解决方案1]
|
||||
|
||||
---
|
||||
|
||||
Q: [产品设计问题2]
|
||||
A: [设计决策说明2]
|
||||
|
||||
## 💡 重要观点
|
||||
|
||||
### 关于产品定位
|
||||
> "[对产品市场定位、核心价值的关键判断]"
|
||||
|
||||
### 关于技术选型
|
||||
> "[对技术架构、开发工具选择的专业建议]"
|
||||
|
||||
### 关于用户体验
|
||||
> "[对用户需求、交互设计的深度洞察]"
|
||||
|
||||
### 关于商业价值
|
||||
> "[对盈利模式、市场前景的战略思考]"
|
||||
|
||||
### 核心共识
|
||||
> "[团队达成的最重要产品开发共识]"
|
||||
|
||||
## 📊 开发决策
|
||||
|
||||
- 技术决策: [确定的技术方案和架构选择]
|
||||
- 功能决策: [优先开发的功能和延后的功能]
|
||||
- 资源决策: [人员调配和预算分配调整]
|
||||
|
||||
## 📌 后续行动
|
||||
|
||||
- [ ] 具体行动项目1
|
||||
- [ ] 具体行动项目2
|
||||
- [ ] 具体行动项目3
|
||||
- [ ] 具体行动项目4
|
||||
- [ ] 具体行动项目5
|
||||
- [ ] 具体行动项目6
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
# 会议记录
|
||||
|
||||
议 题:合川分公司周例会(2026第X期)
|
||||
|
||||
时 间:2026年X月X日X:XX—XX:XX
|
||||
|
||||
地 点:分公司X楼会议室
|
||||
|
||||
主持人:XXX
|
||||
|
||||
参加人:分公司领导 部门经理人员 AI云数中心经理
|
||||
|
||||
议程:
|
||||
|
||||
一、各部门汇报
|
||||
|
||||
二、分公司领导指示部署
|
||||
|
||||
---
|
||||
|
||||
## 会议内容
|
||||
|
||||
### 一、市场部、政企部、建维部、综合部︱党群纪检部按议程现场按顺序做汇报。综合部按照领导部署通报周例会领导部署工作推进完成情况:2026年重点工作跟踪本周完结XX项(政企、综合、建维各完成XX项),待跟进XX项(市场XX项、政企+市场X项),详见汇报材料。
|
||||
|
||||
---
|
||||
|
||||
### 二、部署强调
|
||||
|
||||
#### X总强调:
|
||||
|
||||
1. **政企方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
2. **云数方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
3. **建维方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
---
|
||||
|
||||
#### X总强调:
|
||||
|
||||
1. **市场方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
2. **综合方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
---
|
||||
|
||||
#### X总强调:
|
||||
|
||||
1. **市场方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
2. **政企方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
3. **网络方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
4. **综合方面:**
|
||||
- XXX
|
||||
- XXX
|
||||
- XXX
|
||||
|
||||
---
|
||||
|
||||
📝 **使用说明(输出时请删除):**
|
||||
- 会议内容第一部分以一段文字根据实际汇报人员和回报内容总结关键汇报内容
|
||||
- 保留一级结构,二级和三级内容根据实际会议内容动态生成
|
||||
- 请将 `X`、`XX` 等占位符替换为实际内容
|
||||
- 会议中没被提到的占位符保留,不做替换
|
||||
- 领导强调方面总结为精简的词组,不宜过长
|
||||
- 无事实依据支撑的小节、问答、决策或行动项直接省略
|
||||
- 不要为了凑模板强行写“无相关内容”
|
||||
- 议题数量可增减,不强制必须正好 3 个
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,449 @@
|
|||
import asyncio
|
||||
import json
|
||||
import queue
|
||||
import shutil
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(PROJECT_ROOT))
|
||||
|
||||
from fastapi import FastAPI, HTTPException, UploadFile, File, Form, Request
|
||||
from fastapi.responses import FileResponse, StreamingResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from agents.chat import get_qwen_response
|
||||
from prompt_loader import load_prompt
|
||||
|
||||
FRONTEND_DIR = PROJECT_ROOT / "frontend"
|
||||
FRONTEND_ASSETS_DIR = FRONTEND_DIR / "assets"
|
||||
DATA_ROOT = PROJECT_ROOT / "data"
|
||||
DATA_DIR = DATA_ROOT / "meetings"
|
||||
RESULTS_MD_DIR = PROJECT_ROOT / "data" / "results" / "md"
|
||||
RESULTS_JSON_DIR = PROJECT_ROOT / "data" / "results" / "json"
|
||||
TEMPLATE_DIR = PROJECT_ROOT / "template"
|
||||
EXAMPLES_DIR = PROJECT_ROOT / "examples"
|
||||
CONFIG_FILE = PROJECT_ROOT / "config.json"
|
||||
APP_STATE_FILE = DATA_ROOT / "app_state.json"
|
||||
|
||||
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
RESULTS_MD_DIR.mkdir(parents=True, exist_ok=True)
|
||||
RESULTS_JSON_DIR.mkdir(parents=True, exist_ok=True)
|
||||
FRONTEND_ASSETS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
ALL_RESULT_DIRS = (RESULTS_MD_DIR, RESULTS_JSON_DIR)
|
||||
|
||||
app = FastAPI(title="Meeting Summary Web")
|
||||
|
||||
app.mount("/assets", StaticFiles(directory=str(FRONTEND_ASSETS_DIR)), name="assets")
|
||||
|
||||
|
||||
def _load_config() -> dict:
|
||||
if CONFIG_FILE.exists():
|
||||
return json.loads(CONFIG_FILE.read_text(encoding="utf-8"))
|
||||
return {
|
||||
"api_base_url": "http://10.100.53.199:9527/v1",
|
||||
"api_key": "unis123",
|
||||
"model_name": "Qwen3.6-35B",
|
||||
}
|
||||
|
||||
|
||||
def _save_config(cfg: dict):
|
||||
CONFIG_FILE.write_text(json.dumps(cfg, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
|
||||
|
||||
def _load_app_state() -> dict:
|
||||
if APP_STATE_FILE.exists():
|
||||
return json.loads(APP_STATE_FILE.read_text(encoding="utf-8"))
|
||||
return {"active_meeting_id": None}
|
||||
|
||||
|
||||
def _save_app_state(state: dict):
|
||||
APP_STATE_FILE.write_text(json.dumps(state, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
|
||||
|
||||
def _set_active_meeting(meeting_id: str | None):
|
||||
state = _load_app_state()
|
||||
state["active_meeting_id"] = meeting_id
|
||||
_save_app_state(state)
|
||||
|
||||
|
||||
def _get_llm_client(cfg: dict):
|
||||
from openai import OpenAI
|
||||
return OpenAI(api_key=cfg["api_key"], base_url=cfg["api_base_url"])
|
||||
|
||||
|
||||
def _llm_stream(client, model, system_prompt, user_prompt, max_token=64000):
|
||||
response = client.chat.completions.create(
|
||||
model=model,
|
||||
messages=[
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": user_prompt},
|
||||
],
|
||||
temperature=0.7,
|
||||
max_tokens=max_token,
|
||||
stream=True,
|
||||
)
|
||||
for chunk in response:
|
||||
delta = chunk.choices[0].delta
|
||||
if delta.content is None:
|
||||
yield "reasoning", delta.reasoning
|
||||
else:
|
||||
yield "content", delta.content
|
||||
|
||||
|
||||
def _read_meeting_meta(meeting_id: str) -> dict:
|
||||
meta_path = DATA_DIR / meeting_id / "meta.json"
|
||||
if meta_path.exists():
|
||||
return json.loads(meta_path.read_text(encoding="utf-8"))
|
||||
return {"name": meeting_id, "created_at": ""}
|
||||
|
||||
|
||||
def _write_meeting_meta(meeting_id: str, meta: dict):
|
||||
meta_path = DATA_DIR / meeting_id / "meta.json"
|
||||
meta_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
meta_path.write_text(json.dumps(meta, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
|
||||
|
||||
def _find_transcript_file(meeting_id: str) -> Path | None:
|
||||
mdir = DATA_DIR / meeting_id
|
||||
for ext in (".txt", ".md"):
|
||||
fp = mdir / f"transcript{ext}"
|
||||
if fp.exists():
|
||||
return fp
|
||||
return None
|
||||
|
||||
|
||||
def _meeting_summary(meeting_id: str) -> dict:
|
||||
meta = _read_meeting_meta(meeting_id)
|
||||
transcript_file = _find_transcript_file(meeting_id)
|
||||
result_md = RESULTS_MD_DIR / meeting_id / "meeting_summary.md"
|
||||
result_json = RESULTS_JSON_DIR / meeting_id / "sub_topic.json"
|
||||
return {
|
||||
"id": meeting_id,
|
||||
"name": meta.get("name", meeting_id),
|
||||
"created_at": meta.get("created_at", ""),
|
||||
"original_filename": meta.get("original_filename", ""),
|
||||
"transcript_filename": transcript_file.name if transcript_file else "",
|
||||
"has_transcript": transcript_file is not None,
|
||||
"has_summary": result_md.exists(),
|
||||
"has_topics": result_json.exists(),
|
||||
}
|
||||
|
||||
|
||||
def _list_meeting_ids() -> list[str]:
|
||||
if not DATA_DIR.exists():
|
||||
return []
|
||||
return sorted(
|
||||
[p.name for p in DATA_DIR.iterdir() if p.is_dir()],
|
||||
reverse=True,
|
||||
)
|
||||
|
||||
|
||||
def _list_meetings() -> list[dict]:
|
||||
return [_meeting_summary(meeting_id) for meeting_id in _list_meeting_ids()]
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def index():
|
||||
return FileResponse(str(FRONTEND_DIR / "index.html"))
|
||||
|
||||
|
||||
@app.get("/api/settings")
|
||||
async def get_settings():
|
||||
return _load_config()
|
||||
|
||||
|
||||
@app.put("/api/settings")
|
||||
async def save_settings(cfg: dict):
|
||||
required = {"api_base_url", "api_key", "model_name"}
|
||||
if not required.issubset(cfg.keys()):
|
||||
raise HTTPException(400, f"Missing fields: {required - set(cfg.keys())}")
|
||||
_save_config(cfg)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@app.get("/api/tree")
|
||||
async def file_tree():
|
||||
active_meeting_id = _load_app_state().get("active_meeting_id")
|
||||
tree = {"name": "workspace", "type": "folder", "children": []}
|
||||
|
||||
def _build_branch(label, base_dir, prefix, delete_mode):
|
||||
branch = {"name": label, "type": "folder", "children": []}
|
||||
if base_dir.exists():
|
||||
for md in sorted(base_dir.iterdir()):
|
||||
if not md.is_dir():
|
||||
continue
|
||||
meta = _read_meeting_meta(md.name)
|
||||
children = []
|
||||
for f in sorted(md.iterdir()):
|
||||
if f.is_file() and f.name != "meta.json":
|
||||
children.append({
|
||||
"name": f.name,
|
||||
"type": "file",
|
||||
"path": f"{prefix}/{md.name}/{f.name}",
|
||||
})
|
||||
branch["children"].append({
|
||||
"name": meta.get("name", md.name),
|
||||
"type": "folder",
|
||||
"id": md.name,
|
||||
"active": md.name == active_meeting_id,
|
||||
"delete_mode": delete_mode,
|
||||
"children": children,
|
||||
})
|
||||
tree["children"].append(branch)
|
||||
|
||||
_build_branch("会议原文", DATA_DIR, "meetings", "meeting")
|
||||
_build_branch("处理结果MD", RESULTS_MD_DIR, "results_md", "results")
|
||||
_build_branch("处理结果JSON", RESULTS_JSON_DIR, "results_json", "results")
|
||||
|
||||
return tree
|
||||
|
||||
|
||||
@app.get("/api/meetings")
|
||||
async def list_meetings():
|
||||
active_meeting_id = _load_app_state().get("active_meeting_id")
|
||||
return {
|
||||
"active_meeting_id": active_meeting_id,
|
||||
"meetings": _list_meetings(),
|
||||
}
|
||||
|
||||
|
||||
@app.get("/api/current-meeting")
|
||||
async def get_current_meeting():
|
||||
active_meeting_id = _load_app_state().get("active_meeting_id")
|
||||
if not active_meeting_id:
|
||||
return {"active_meeting_id": None, "meeting": None}
|
||||
if not (DATA_DIR / active_meeting_id).exists():
|
||||
_set_active_meeting(None)
|
||||
return {"active_meeting_id": None, "meeting": None}
|
||||
return {
|
||||
"active_meeting_id": active_meeting_id,
|
||||
"meeting": _meeting_summary(active_meeting_id),
|
||||
}
|
||||
|
||||
|
||||
@app.put("/api/current-meeting")
|
||||
async def set_current_meeting(payload: dict):
|
||||
meeting_id = payload.get("meeting_id")
|
||||
if meeting_id is not None and not (DATA_DIR / meeting_id).exists():
|
||||
raise HTTPException(404, "Meeting not found")
|
||||
_set_active_meeting(meeting_id)
|
||||
return {
|
||||
"ok": True,
|
||||
"active_meeting_id": meeting_id,
|
||||
"meeting": _meeting_summary(meeting_id) if meeting_id else None,
|
||||
}
|
||||
|
||||
|
||||
@app.post("/api/meetings/import")
|
||||
async def import_meeting(name: str = Form(...), file: UploadFile = File(...)):
|
||||
if not file.filename:
|
||||
raise HTTPException(400, "No file selected")
|
||||
ext = Path(file.filename).suffix.lower()
|
||||
if ext not in (".txt", ".md"):
|
||||
raise HTTPException(400, "Only .txt and .md files are supported")
|
||||
|
||||
mid = str(int(time.time() * 1000))
|
||||
mdir = DATA_DIR / mid
|
||||
mdir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
content = await file.read()
|
||||
try:
|
||||
text = content.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
text = content.decode("gbk", errors="replace")
|
||||
|
||||
dest = "transcript" + ext
|
||||
(mdir / dest).write_text(text, encoding="utf-8")
|
||||
|
||||
_write_meeting_meta(mid, {
|
||||
"name": name,
|
||||
"created_at": time.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"original_filename": file.filename,
|
||||
})
|
||||
_set_active_meeting(mid)
|
||||
return {"id": mid, "name": name}
|
||||
|
||||
|
||||
@app.delete("/api/meetings/{meeting_id}")
|
||||
async def delete_meeting(meeting_id: str):
|
||||
if not (DATA_DIR / meeting_id).exists():
|
||||
raise HTTPException(404, "Meeting not found")
|
||||
active_meeting_id = _load_app_state().get("active_meeting_id")
|
||||
for base in (DATA_DIR, RESULTS_MD_DIR, RESULTS_JSON_DIR):
|
||||
bd = base / meeting_id
|
||||
if bd.exists():
|
||||
shutil.rmtree(str(bd))
|
||||
if active_meeting_id == meeting_id:
|
||||
remaining = _list_meeting_ids()
|
||||
_set_active_meeting(remaining[0] if remaining else None)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@app.delete("/api/meetings/{meeting_id}/results")
|
||||
async def delete_meeting_results(meeting_id: str):
|
||||
deleted = False
|
||||
for base in (RESULTS_MD_DIR, RESULTS_JSON_DIR):
|
||||
bd = base / meeting_id
|
||||
if bd.exists():
|
||||
shutil.rmtree(str(bd))
|
||||
deleted = True
|
||||
if not deleted:
|
||||
raise HTTPException(404, "Meeting results not found")
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@app.get("/api/meetings/{meeting_id}/file/{filename:path}")
|
||||
async def get_meeting_file(meeting_id: str, filename: str):
|
||||
for base in (DATA_DIR, RESULTS_MD_DIR, RESULTS_JSON_DIR):
|
||||
fp = base / meeting_id / filename
|
||||
if fp.exists():
|
||||
return {"content": fp.read_text(encoding="utf-8"), "filename": filename}
|
||||
raise HTTPException(404, f"File not found: {filename}")
|
||||
|
||||
|
||||
@app.get("/api/examples/{filename:path}")
|
||||
async def get_example_file(filename: str):
|
||||
fp = EXAMPLES_DIR / filename
|
||||
if not fp.exists():
|
||||
raise HTTPException(404, f"File not found: {filename}")
|
||||
return {"content": fp.read_text(encoding="utf-8"), "filename": filename}
|
||||
|
||||
|
||||
@app.get("/api/templates")
|
||||
async def list_templates():
|
||||
templates = []
|
||||
if TEMPLATE_DIR.exists():
|
||||
for f in sorted(TEMPLATE_DIR.iterdir()):
|
||||
if f.is_file() and f.suffix == ".md":
|
||||
templates.append({"name": f.name})
|
||||
return templates
|
||||
|
||||
|
||||
@app.get("/api/templates/{name}")
|
||||
async def get_template(name: str):
|
||||
fp = TEMPLATE_DIR / name
|
||||
if not fp.exists():
|
||||
raise HTTPException(404, f"Template not found: {name}")
|
||||
return {"name": name, "content": fp.read_text(encoding="utf-8")}
|
||||
|
||||
|
||||
@app.put("/api/templates/{name}")
|
||||
async def save_template(name: str, payload: dict):
|
||||
content = payload.get("content")
|
||||
if content is None:
|
||||
raise HTTPException(400, "Missing content field")
|
||||
(TEMPLATE_DIR / name).write_text(content, encoding="utf-8")
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@app.get("/api/meetings/{meeting_id}/transcript")
|
||||
async def get_meeting_transcript(meeting_id: str):
|
||||
fp = _find_transcript_file(meeting_id)
|
||||
if fp:
|
||||
return {"content": fp.read_text(encoding="utf-8"), "filename": fp.name}
|
||||
raise HTTPException(404, "No transcript found")
|
||||
|
||||
|
||||
@app.get("/api/meetings/{meeting_id}/process")
|
||||
async def process_meeting(meeting_id: str, request: Request, template_name: str = "template1.md"):
|
||||
mdir = DATA_DIR / meeting_id
|
||||
if not mdir.exists():
|
||||
raise HTTPException(404, "Meeting not found")
|
||||
_set_active_meeting(meeting_id)
|
||||
|
||||
transcript_file = _find_transcript_file(meeting_id)
|
||||
if transcript_file is None:
|
||||
raise HTTPException(400, "No transcript found")
|
||||
transcript = transcript_file.read_text(encoding="utf-8")
|
||||
|
||||
tpl_path = TEMPLATE_DIR / template_name
|
||||
if not tpl_path.exists():
|
||||
raise HTTPException(404, f"Template not found: {template_name}")
|
||||
template_content = tpl_path.read_text(encoding="utf-8")
|
||||
|
||||
prompt = load_prompt("meeting_summary", "zh")
|
||||
|
||||
cfg = _load_config()
|
||||
model_name = cfg["model_name"]
|
||||
|
||||
eq = queue.Queue()
|
||||
|
||||
def run():
|
||||
try:
|
||||
client = _get_llm_client(cfg)
|
||||
|
||||
eq.put({"type": "status", "data": "preprocessing"})
|
||||
|
||||
sp = prompt["system"]["role"] + prompt["mode_contracts"]["data_preproces"]
|
||||
up = prompt["user_template"]["article_preproces"].format(article=transcript)
|
||||
|
||||
sub = ""
|
||||
for ct, cc in _llm_stream(client, model_name, sp, up):
|
||||
if cc:
|
||||
eq.put({"type": "chunk", "data": {"stage": 1, "chunk_type": ct, "text": str(cc)}})
|
||||
if ct == "content":
|
||||
sub += str(cc)
|
||||
|
||||
eq.put({"type": "status", "data": "preprocessing_done"})
|
||||
|
||||
rjdir = RESULTS_JSON_DIR / meeting_id
|
||||
rjdir.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
sd = json.loads(sub)
|
||||
(rjdir / "sub_topic.json").write_text(json.dumps(sd, ensure_ascii=False, indent=4), encoding="utf-8")
|
||||
except Exception:
|
||||
(rjdir / "sub_topic.json").write_text(sub, encoding="utf-8")
|
||||
|
||||
eq.put({"type": "status", "data": "summarizing"})
|
||||
|
||||
sp = prompt["system"]["role"] + prompt["mode_contracts"]["data_summary"].format(template=template_content)
|
||||
up = prompt["user_template"]["article_summary"].format(article=transcript, sub_topices=sub)
|
||||
|
||||
result = ""
|
||||
for ct, cc in _llm_stream(client, model_name, sp, up):
|
||||
if cc:
|
||||
eq.put({"type": "chunk", "data": {"stage": 2, "chunk_type": ct, "text": str(cc)}})
|
||||
if ct == "content":
|
||||
result += str(cc)
|
||||
|
||||
rmdir = RESULTS_MD_DIR / meeting_id
|
||||
rmdir.mkdir(parents=True, exist_ok=True)
|
||||
(rmdir / "meeting_summary.md").write_text(result, encoding="utf-8")
|
||||
eq.put({"type": "done", "data": {"result": result}})
|
||||
|
||||
except Exception as e:
|
||||
eq.put({"type": "error", "data": str(e)})
|
||||
|
||||
threading.Thread(target=run, daemon=True).start()
|
||||
|
||||
async def gen():
|
||||
loop = asyncio.get_running_loop()
|
||||
while True:
|
||||
if await request.is_disconnected():
|
||||
break
|
||||
try:
|
||||
evt = await loop.run_in_executor(None, eq.get, True, 0.5)
|
||||
yield f"data: {json.dumps(evt, ensure_ascii=False)}\n\n"
|
||||
if evt["type"] in ("done", "error"):
|
||||
break
|
||||
except queue.Empty:
|
||||
yield ": heartbeat\n\n"
|
||||
|
||||
return StreamingResponse(
|
||||
gen(),
|
||||
media_type="text/event-stream",
|
||||
headers={
|
||||
"Cache-Control": "no-cache",
|
||||
"X-Accel-Buffering": "no",
|
||||
"Connection": "keep-alive",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
|
|
@ -0,0 +1,967 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Meeting Summary</title>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/13.0.3/marked.min.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f0f2f5;
|
||||
--panel-bg: #fff;
|
||||
--border: #e4e7ed;
|
||||
--text: #303133;
|
||||
--text2: #909399;
|
||||
--accent: #409eff;
|
||||
--accent-light: #ecf5ff;
|
||||
--hover: #f5f7fa;
|
||||
--selected: #ecf5ff;
|
||||
--header-h: 42px;
|
||||
--panel-header-h: 36px;
|
||||
--gutter-w: 4px;
|
||||
--danger: #f56c6c;
|
||||
--radius: 4px;
|
||||
--font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Microsoft YaHei",sans-serif;
|
||||
--mono: "Cascadia Code","Fira Code","JetBrains Mono",Consolas,monospace;
|
||||
}
|
||||
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body { height: 100%; overflow: hidden; }
|
||||
body { font-family: var(--font); background: var(--bg); color: var(--text); font-size: 13px; }
|
||||
|
||||
.app { display: flex; flex-direction: column; height: 100vh; }
|
||||
|
||||
/* ─── Header ─── */
|
||||
.header {
|
||||
height: var(--header-h);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 16px;
|
||||
background: var(--panel-bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
user-select: none;
|
||||
}
|
||||
.header .title { font-size: 14px; font-weight: 600; letter-spacing: -0.2px; }
|
||||
.header .btns { display: flex; gap: 6px; }
|
||||
|
||||
/* ─── Main area ─── */
|
||||
.main { display: flex; flex: 1; overflow: hidden; position: relative; }
|
||||
|
||||
.panel {
|
||||
height: 100%;
|
||||
background: var(--panel-bg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.panel-header {
|
||||
height: var(--panel-header-h);
|
||||
min-height: var(--panel-header-h);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 10px;
|
||||
background: #fafbfc;
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-size: 12px;
|
||||
color: var(--text2);
|
||||
gap: 4px;
|
||||
user-select: none;
|
||||
}
|
||||
.panel-body { flex: 1; overflow: auto; }
|
||||
|
||||
/* ─── Resize gutter ─── */
|
||||
.gutter {
|
||||
width: var(--gutter-w);
|
||||
background: var(--border);
|
||||
cursor: col-resize;
|
||||
flex-shrink: 0;
|
||||
transition: background 0.15s;
|
||||
position: relative;
|
||||
}
|
||||
.gutter:hover, .gutter.dragging { background: var(--accent); }
|
||||
|
||||
/* ─── File Tree ─── */
|
||||
#sidebar { flex-basis: 220px; flex-shrink: 0; }
|
||||
#sidebar .panel-body { padding: 2px 0; overflow-y: auto; }
|
||||
|
||||
.tree { font-size: 13px; user-select: none; }
|
||||
.tree-node { }
|
||||
.tree-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 28px;
|
||||
padding: 0 4px;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
gap: 2px;
|
||||
}
|
||||
.tree-row:hover { background: var(--hover); }
|
||||
.tree-row.selected { background: var(--selected); color: var(--accent); }
|
||||
.tree-row .arrow {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 8px;
|
||||
color: var(--text2);
|
||||
flex-shrink: 0;
|
||||
transition: transform 0.1s;
|
||||
}
|
||||
.tree-row .arrow.expanded { transform: rotate(90deg); }
|
||||
.tree-row .arrow.none { visibility: hidden; }
|
||||
.tree-row .icon { flex-shrink: 0; width: 18px; text-align: center; font-size: 14px; }
|
||||
.tree-row .label { overflow: hidden; text-overflow: ellipsis; flex: 1; }
|
||||
.tree-row .del-btn {
|
||||
display: none;
|
||||
margin-left: auto;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 2px;
|
||||
color: var(--text2);
|
||||
}
|
||||
.tree-row:hover .del-btn { display: block; }
|
||||
.tree-row .del-btn:hover { color: #fff; background: var(--danger); border-radius: 2px; }
|
||||
.tree-children { display: none; }
|
||||
.tree-children.open { display: block; }
|
||||
|
||||
/* ─── Buttons ─── */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
padding: 5px 11px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
background: #fff;
|
||||
color: var(--text);
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
font-family: var(--font);
|
||||
white-space: nowrap;
|
||||
transition: all 0.12s;
|
||||
height: 28px;
|
||||
}
|
||||
.btn:hover { border-color: var(--accent); color: var(--accent); }
|
||||
.btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
|
||||
.btn.primary:hover { background: #337ecc; }
|
||||
.btn.sm { padding: 2px 8px; font-size: 11px; height: 24px; }
|
||||
.btn:disabled { opacity: .45; cursor: not-allowed; pointer-events: none; }
|
||||
|
||||
select.btn {
|
||||
appearance: none;
|
||||
padding-right: 22px;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23909399' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 6px center;
|
||||
background-size: 10px;
|
||||
}
|
||||
select.btn:hover { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23409eff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); }
|
||||
|
||||
/* ─── Result Panel ─── */
|
||||
#result-panel { flex: 1; min-width: 320px; }
|
||||
|
||||
#result-empty, #processing-indicator {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
color: var(--text2);
|
||||
gap: 10px;
|
||||
}
|
||||
#result-md { display: none; padding: 12px 16px; line-height: 1.8; font-size: 14px; color: #1f2937; height: 100%; }
|
||||
|
||||
#processing-indicator .spinner {
|
||||
width: 30px; height: 30px;
|
||||
border: 3px solid #e4e7ed;
|
||||
border-top-color: var(--accent);
|
||||
border-radius: 50%;
|
||||
animation: spin .65s linear infinite;
|
||||
}
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
#stream-box {
|
||||
margin-top: 12px;
|
||||
background: #f9fafb;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
max-width: 85%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
display: none;
|
||||
}
|
||||
#stream-title {
|
||||
text-align: center;
|
||||
padding: 5px 10px;
|
||||
background: #ebeef5;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
color: var(--text);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#stream-content {
|
||||
margin: 0;
|
||||
padding: 6px 10px;
|
||||
background: #f9fafb;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
color: #555;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
max-height: 90px;
|
||||
overflow-y: auto;
|
||||
min-height: 38px;
|
||||
}
|
||||
|
||||
/* ─── Template Panel ─── */
|
||||
#template-panel { flex-basis: 360px; flex-shrink: 0; min-width: 260px; }
|
||||
|
||||
#template-tab { height: 100%; }
|
||||
#template-editor {
|
||||
width: 100%; height: 100%;
|
||||
border: none;
|
||||
padding: 12px;
|
||||
font-family: var(--mono);
|
||||
font-size: 13px;
|
||||
line-height: 1.65;
|
||||
resize: none;
|
||||
outline: none;
|
||||
color: var(--text);
|
||||
background: #fafbfd;
|
||||
display: none;
|
||||
}
|
||||
#template-preview { display: block; padding: 12px 16px; height: 100%; }
|
||||
#template-body { position: relative; }
|
||||
|
||||
.panel-tabs {
|
||||
display: flex;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
height: 24px;
|
||||
}
|
||||
.panel-tabs .tab {
|
||||
padding: 2px 10px;
|
||||
font-size: 11px;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
color: var(--text2);
|
||||
transition: all 0.12s;
|
||||
user-select: none;
|
||||
}
|
||||
.panel-tabs .tab:hover { color: var(--accent); }
|
||||
.panel-tabs .tab.active { background: var(--accent); color: #fff; }
|
||||
.panel-tabs .tab + .tab { border-left: 1px solid var(--border); }
|
||||
#original-content {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 12px 16px;
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
overflow-y: auto;
|
||||
color: var(--text);
|
||||
background: #fafbfd;
|
||||
}
|
||||
|
||||
/* ─── Markdown content ─── */
|
||||
.md-content h1 { font-size: 1.5em; margin: .6em 0 .3em; border-bottom: 1px solid var(--border); padding-bottom: .2em; }
|
||||
.md-content h2 { font-size: 1.3em; margin: .6em 0 .3em; }
|
||||
.md-content h3 { font-size: 1.1em; margin: .5em 0 .2em; }
|
||||
.md-content p { margin: .4em 0; }
|
||||
.md-content ul, .md-content ol { padding-left: 1.5em; margin: .3em 0; }
|
||||
.md-content li { margin: 2px 0; }
|
||||
.md-content code { background: #f0f2f5; padding: 1px 5px; border-radius: 3px; font-family: var(--mono); font-size: .88em; }
|
||||
.md-content pre { background: #282c34; color: #abb2bf; padding: 12px 16px; border-radius: 6px; overflow-x: auto; margin: .5em 0; }
|
||||
.md-content pre code { background: none; padding: 0; color: inherit; }
|
||||
.md-content blockquote { border-left: 3px solid var(--accent); padding: 2px 12px; margin: .5em 0; color: var(--text2); background: var(--accent-light); }
|
||||
.md-content hr { border: none; border-top: 1px solid var(--border); margin: .8em 0; }
|
||||
.md-content table { border-collapse: collapse; width: 100%; margin: .5em 0; }
|
||||
.md-content th, .md-content td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
|
||||
.md-content th { background: #f9fafb; }
|
||||
.md-content a { color: var(--accent); }
|
||||
.md-content img { max-width: 100%; }
|
||||
|
||||
/* ─── Modal ─── */
|
||||
.modal-mask {
|
||||
position: fixed; inset: 0;
|
||||
background: rgba(0,0,0,0.35);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.modal-mask.show { display: flex; }
|
||||
.modal-box {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 30px rgba(0,0,0,0.15);
|
||||
width: 460px;
|
||||
max-width: 94vw;
|
||||
padding: 22px 24px;
|
||||
max-height: 85vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.modal-box h3 { font-size: 15px; margin-bottom: 18px; }
|
||||
.form-field { margin-bottom: 12px; }
|
||||
.form-field label { display: block; font-size: 12px; color: var(--text2); margin-bottom: 4px; font-weight: 500; }
|
||||
.form-field input {
|
||||
width: 100%;
|
||||
padding: 7px 10px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
font-size: 13px;
|
||||
font-family: var(--font);
|
||||
outline: none;
|
||||
transition: border-color 0.12s;
|
||||
}
|
||||
.form-field input:focus { border-color: var(--accent); }
|
||||
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }
|
||||
|
||||
/* ─── Toast ─── */
|
||||
.toast {
|
||||
position: fixed; top: 16px; right: 16px;
|
||||
padding: 10px 16px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
z-index: 2000;
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
transition: all .2s;
|
||||
pointer-events: none;
|
||||
}
|
||||
.toast.show { opacity: 1; transform: translateY(0); }
|
||||
.toast.ok { background: #f0f9eb; color: #67c23a; border: 1px solid #e1f3d8; }
|
||||
.toast.err { background: #fef0f0; color: #f56c6c; border: 1px solid #fde2e2; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<div class="header">
|
||||
<span class="title">Meeting Summary</span>
|
||||
<div class="btns">
|
||||
<button class="btn primary" id="btn-import">+ 导入会议</button>
|
||||
<button class="btn" id="btn-settings">⚙ 设置</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="main" id="main-container">
|
||||
<!-- Left: File Tree -->
|
||||
<div class="panel" id="sidebar">
|
||||
<div class="panel-header">文件资源管理器</div>
|
||||
<div class="panel-body"><div class="tree" id="file-tree"></div></div>
|
||||
</div>
|
||||
<div class="gutter" id="gutter-1"></div>
|
||||
<!-- Center: Result -->
|
||||
<div class="panel" id="result-panel">
|
||||
<div class="panel-header">
|
||||
<span>处理结果</span>
|
||||
<button class="btn sm primary" id="btn-process" disabled>▶ 处理</button>
|
||||
</div>
|
||||
<div class="panel-body" id="result-body">
|
||||
<div id="result-empty"><span style="font-size:36px;opacity:.25">📄</span><span>选择左侧会议后点击「处理」</span></div>
|
||||
<div id="processing-indicator" style="display:none">
|
||||
<div class="spinner"></div>
|
||||
<div id="stream-box">
|
||||
<div id="stream-title"></div>
|
||||
<pre id="stream-content"></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div id="result-md" class="md-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gutter" id="gutter-2"></div>
|
||||
<!-- Right: Template Editor -->
|
||||
<div class="panel" id="template-panel">
|
||||
<div class="panel-header">
|
||||
<span>模板编辑器</span>
|
||||
<div style="display:flex;gap:4px;align-items:center;">
|
||||
<div class="panel-tabs" id="panel-tabs">
|
||||
<span class="tab active" data-tab="template">模板</span>
|
||||
<span class="tab" data-tab="original">原文</span>
|
||||
</div>
|
||||
<span style="font-size:12px;color:var(--text2);">选择模板:</span>
|
||||
<select class="btn sm" id="tpl-select"></select>
|
||||
<button class="btn sm" id="btn-toggle-edit">✏ 编辑</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" id="template-body">
|
||||
<div id="template-tab">
|
||||
<textarea id="template-editor" spellcheck="false"></textarea>
|
||||
<div id="template-preview" class="md-content"></div>
|
||||
</div>
|
||||
<div id="original-tab" style="display:none;height:100%;">
|
||||
<pre id="original-content"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Import Modal -->
|
||||
<div class="modal-mask" id="modal-import">
|
||||
<div class="modal-box">
|
||||
<h3>导入会议转录</h3>
|
||||
<div class="form-field">
|
||||
<label>会议名称</label>
|
||||
<input type="text" id="import-name" placeholder="例: 2026-05-08 运维周会">
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label>转录文件 (.txt / .md)</label>
|
||||
<input type="file" id="import-file" accept=".txt,.md">
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn" onclick="closeModal('modal-import')">取消</button>
|
||||
<button class="btn primary" id="btn-confirm-import">导入</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings Modal -->
|
||||
<div class="modal-mask" id="modal-settings">
|
||||
<div class="modal-box">
|
||||
<h3>API 配置</h3>
|
||||
<div class="form-field">
|
||||
<label>Base URL</label>
|
||||
<input type="text" id="cfg-url" placeholder="http://host:port/v1">
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label>API Key</label>
|
||||
<input type="text" id="cfg-key" placeholder="your-api-key">
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label>Model Name</label>
|
||||
<input type="text" id="cfg-model" placeholder="Qwen3.6-35B">
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button class="btn" onclick="closeModal('modal-settings')">取消</button>
|
||||
<button class="btn primary" id="btn-save-settings">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toast" id="toast"></div>
|
||||
|
||||
<script>
|
||||
var $ = function(s) { return document.querySelector(s); };
|
||||
var $$ = function(s) { return document.querySelectorAll(s); };
|
||||
|
||||
var state = {
|
||||
meetingId: null,
|
||||
templateName: 'template1.md',
|
||||
editMode: false,
|
||||
processing: false,
|
||||
templates: [],
|
||||
};
|
||||
|
||||
function toast(msg, type) {
|
||||
var el = $('#toast');
|
||||
el.textContent = msg;
|
||||
el.className = 'toast show ' + (type || 'ok');
|
||||
clearTimeout(el._timer);
|
||||
el._timer = setTimeout(function() { el.classList.remove('show'); }, 2500);
|
||||
}
|
||||
|
||||
function closeModal(id) {
|
||||
$('#' + id).classList.remove('show');
|
||||
}
|
||||
|
||||
function openModal(id) {
|
||||
$('#' + id).classList.add('show');
|
||||
}
|
||||
|
||||
async function api(url, opts) {
|
||||
var res = await fetch(url, opts || {});
|
||||
if (!res.ok) {
|
||||
var e = await res.json().catch(function() { return { detail: res.statusText }; });
|
||||
throw new Error(e.detail || 'Request failed');
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
// ─── Resizable Panels ───
|
||||
function initResize(gutterId, leftId, rightId) {
|
||||
var gutter = document.getElementById(gutterId);
|
||||
var left = document.getElementById(leftId);
|
||||
var right = document.getElementById(rightId);
|
||||
var container = document.getElementById('main-container');
|
||||
var dragging = false;
|
||||
var startX = 0;
|
||||
var startLeftW = 0;
|
||||
var startRightW = 0;
|
||||
|
||||
gutter.addEventListener('mousedown', function(e) {
|
||||
e.preventDefault();
|
||||
dragging = true;
|
||||
gutter.classList.add('dragging');
|
||||
startX = e.clientX;
|
||||
startLeftW = left.getBoundingClientRect().width;
|
||||
startRightW = right.getBoundingClientRect().width;
|
||||
document.body.style.cursor = 'col-resize';
|
||||
document.body.style.userSelect = 'none';
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', function(e) {
|
||||
if (!dragging) return;
|
||||
var dx = e.clientX - startX;
|
||||
var newLeftW = Math.max(left.dataset.minWidth || 150, startLeftW + dx);
|
||||
var newRightW = startRightW - dx;
|
||||
var minRight = right.dataset.minWidth || 200;
|
||||
if (newRightW < minRight) {
|
||||
newRightW = minRight;
|
||||
newLeftW = startLeftW + startRightW - minRight;
|
||||
}
|
||||
if (leftId === 'sidebar') {
|
||||
left.style.flexBasis = newLeftW + 'px';
|
||||
left.style.flexGrow = '0';
|
||||
} else {
|
||||
left.style.flexGrow = '1';
|
||||
left.style.flexBasis = '0%';
|
||||
}
|
||||
right.style.flexBasis = newRightW + 'px';
|
||||
right.style.flexGrow = '0';
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', function() {
|
||||
if (!dragging) return;
|
||||
dragging = false;
|
||||
gutter.classList.remove('dragging');
|
||||
document.body.style.cursor = '';
|
||||
document.body.style.userSelect = '';
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initResize('gutter-1', 'sidebar', 'result-panel');
|
||||
initResize('gutter-2', 'result-panel', 'template-panel');
|
||||
document.getElementById('sidebar').dataset.minWidth = 180;
|
||||
document.getElementById('template-panel').dataset.minWidth = 260;
|
||||
document.getElementById('result-panel').dataset.minWidth = 280;
|
||||
});
|
||||
|
||||
// ─── File Tree ───
|
||||
function buildTree(data) {
|
||||
var el = $('#file-tree');
|
||||
el.innerHTML = '';
|
||||
(data.children || []).forEach(function(n) { renderNode(n, el, 0); });
|
||||
}
|
||||
|
||||
function renderNode(node, parent, depth) {
|
||||
var div = document.createElement('div');
|
||||
div.className = 'tree-node';
|
||||
|
||||
var row = document.createElement('div');
|
||||
row.className = 'tree-row';
|
||||
row.style.paddingLeft = (8 + depth * 18) + 'px';
|
||||
|
||||
if (node.type === 'folder') {
|
||||
var arrow = document.createElement('span');
|
||||
arrow.className = 'arrow';
|
||||
arrow.textContent = '▸';
|
||||
row.appendChild(arrow);
|
||||
|
||||
var icon = document.createElement('span');
|
||||
icon.className = 'icon';
|
||||
icon.textContent = '📁';
|
||||
row.appendChild(icon);
|
||||
|
||||
var label = document.createElement('span');
|
||||
label.className = 'label';
|
||||
label.textContent = node.name;
|
||||
row.appendChild(label);
|
||||
|
||||
if (node.id) {
|
||||
var del = document.createElement('span');
|
||||
del.className = 'del-btn';
|
||||
del.textContent = '×';
|
||||
del.addEventListener('click', function(e) { e.stopPropagation(); deleteMeeting(node.id); });
|
||||
row.appendChild(del);
|
||||
}
|
||||
|
||||
row.addEventListener('click', function() {
|
||||
$$('.tree-row').forEach(function(r) { r.classList.remove('selected'); });
|
||||
row.classList.add('selected');
|
||||
var kids = div.querySelector(':scope > .tree-children');
|
||||
if (kids) {
|
||||
var open = !kids.classList.contains('open');
|
||||
kids.classList.toggle('open', open);
|
||||
arrow.classList.toggle('expanded', open);
|
||||
}
|
||||
if (node.id) { selectMeeting(node.id); }
|
||||
});
|
||||
} else {
|
||||
var arrNone = document.createElement('span');
|
||||
arrNone.className = 'arrow none';
|
||||
row.appendChild(arrNone);
|
||||
|
||||
var ficon = document.createElement('span');
|
||||
ficon.className = 'icon';
|
||||
var n = node.name;
|
||||
ficon.textContent = n.endsWith('.md') ? '📝' : n.endsWith('.json') ? '📊' : n.endsWith('.txt') ? '📃' : '📄';
|
||||
row.appendChild(ficon);
|
||||
|
||||
var flabel = document.createElement('span');
|
||||
flabel.className = 'label';
|
||||
flabel.textContent = n;
|
||||
row.appendChild(flabel);
|
||||
|
||||
row.addEventListener('click', function() {
|
||||
$$('.tree-row').forEach(function(r) { r.classList.remove('selected'); });
|
||||
row.classList.add('selected');
|
||||
|
||||
if (node.path) {
|
||||
var p = node.path;
|
||||
if (p.startsWith('meetings/') || p.startsWith('results_md/') || p.startsWith('results_json/')) {
|
||||
var parts = p.replace(/^(meetings|results_md|results_json)\//, '').split('/');
|
||||
var mid = parts[0];
|
||||
var fname = parts.slice(1).join('/');
|
||||
viewMeetingFile(mid, fname);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
div.appendChild(row);
|
||||
|
||||
if (node.children && node.children.length) {
|
||||
var kids = document.createElement('div');
|
||||
kids.className = 'tree-children';
|
||||
node.children.forEach(function(c) { renderNode(c, kids, depth + 1); });
|
||||
div.appendChild(kids);
|
||||
}
|
||||
|
||||
parent.appendChild(div);
|
||||
}
|
||||
|
||||
// ─── Meetings ───
|
||||
function selectMeeting(mid) {
|
||||
if (state.processing) return;
|
||||
state.meetingId = mid;
|
||||
$('#btn-process').disabled = false;
|
||||
showResultPanel();
|
||||
api('/api/meetings/' + mid + '/file/meeting_summary.md').then(function(r) {
|
||||
showResult(r.content);
|
||||
}).catch(function() {
|
||||
showEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
function viewMeetingFile(mid, fname) {
|
||||
if (state.processing) return;
|
||||
state.meetingId = mid;
|
||||
$('#btn-process').disabled = false;
|
||||
if (fname === 'meeting_summary.md') {
|
||||
switchToOriginalTab(mid);
|
||||
}
|
||||
api('/api/meetings/' + mid + '/file/' + encodeURIComponent(fname)).then(function(r) {
|
||||
var c = r.content;
|
||||
if (fname.endsWith('.json')) {
|
||||
try { c = '```json\n' + JSON.stringify(JSON.parse(c), null, 2) + '\n```'; } catch(e) {}
|
||||
} else if (fname.endsWith('.txt')) {
|
||||
c = '```\n' + c + '\n```';
|
||||
}
|
||||
showResult(c);
|
||||
}).catch(function() { showEmpty(); });
|
||||
}
|
||||
|
||||
function viewExampleFile(fname) {
|
||||
state.meetingId = null;
|
||||
$('#btn-process').disabled = true;
|
||||
api('/api/examples/' + encodeURIComponent(fname)).then(function(r) {
|
||||
var c = r.content;
|
||||
if (fname.endsWith('.json')) {
|
||||
try { c = '```json\n' + JSON.stringify(JSON.parse(c), null, 2) + '\n```'; } catch(e) {}
|
||||
} else if (fname.endsWith('.txt')) {
|
||||
c = '```\n' + c + '\n```';
|
||||
}
|
||||
showResult(c);
|
||||
}).catch(function() { showEmpty(); });
|
||||
}
|
||||
|
||||
function deleteMeeting(mid) {
|
||||
if (!confirm('确定删除此会议及所有数据?')) return;
|
||||
api('/api/meetings/' + mid, { method: 'DELETE' }).then(function() {
|
||||
toast('已删除');
|
||||
if (state.meetingId === mid) { state.meetingId = null; showEmpty(); $('#btn-process').disabled = true; }
|
||||
refresh();
|
||||
}).catch(function(e) { toast(e.message, 'err'); });
|
||||
}
|
||||
|
||||
// ─── Result ───
|
||||
function showResult(md) {
|
||||
$('#processing-indicator').style.display = 'none';
|
||||
$('#result-empty').style.display = 'none';
|
||||
var el = $('#result-md');
|
||||
el.style.display = 'block';
|
||||
el.innerHTML = marked.parse(md);
|
||||
el.scrollTop = 0;
|
||||
}
|
||||
|
||||
function showResultPanel() {
|
||||
$('#result-empty').style.display = 'none';
|
||||
$('#processing-indicator').style.display = 'none';
|
||||
$('#result-md').style.display = 'none';
|
||||
}
|
||||
|
||||
function showEmpty() {
|
||||
$('#processing-indicator').style.display = 'none';
|
||||
$('#result-md').style.display = 'none';
|
||||
$('#result-empty').style.display = 'flex';
|
||||
}
|
||||
|
||||
// ─── Processing (SSE) ───
|
||||
$('#btn-process').addEventListener('click', function() {
|
||||
if (!state.meetingId || state.processing) return;
|
||||
state.processing = true;
|
||||
$('#btn-process').disabled = true;
|
||||
$('#result-empty').style.display = 'none';
|
||||
$('#result-md').style.display = 'none';
|
||||
$('#processing-indicator').style.display = 'flex';
|
||||
$('#stream-title').textContent = '正在预处理...';
|
||||
$('#stream-content').textContent = '';
|
||||
$('#stream-box').style.display = 'block';
|
||||
|
||||
var url = '/api/meetings/' + state.meetingId + '/process?template_name=' + encodeURIComponent(state.templateName);
|
||||
var es = new EventSource(url);
|
||||
var resultAcc = '';
|
||||
var streamAcc = '';
|
||||
|
||||
es.onmessage = function(e) {
|
||||
if (!e.data || e.data.indexOf(': heartbeat') === 0) return;
|
||||
try {
|
||||
var evt = JSON.parse(e.data);
|
||||
if (evt.type === 'status') {
|
||||
if (evt.data === 'preprocessing') { $('#stream-title').textContent = '第一阶段:数据预处理...'; streamAcc = ''; $('#stream-content').textContent = ''; }
|
||||
else if (evt.data === 'preprocessing_done') $('#stream-title').textContent = '第一阶段完成,开始生成总结...';
|
||||
else if (evt.data === 'summarizing') { $('#stream-title').textContent = '第二阶段:生成会议总结...'; streamAcc = ''; $('#stream-content').textContent = ''; }
|
||||
} else if (evt.type === 'chunk') {
|
||||
var d = evt.data;
|
||||
if (d.text) {
|
||||
streamAcc += d.text;
|
||||
var lines = streamAcc.replace(/\r\n/g, '\n').split('\n');
|
||||
var last3 = lines.slice(-3).join('\n');
|
||||
if (last3.trim()) {
|
||||
$('#stream-content').textContent = last3;
|
||||
}
|
||||
}
|
||||
if (d.stage === 2 && d.chunk_type === 'content') {
|
||||
resultAcc += d.text;
|
||||
$('#result-md').style.display = 'block';
|
||||
$('#result-md').innerHTML = marked.parse(resultAcc);
|
||||
$('#result-md').scrollTop = $('#result-md').scrollHeight;
|
||||
}
|
||||
} else if (evt.type === 'done') {
|
||||
es.close();
|
||||
$('#stream-title').textContent = '完成';
|
||||
switchToOriginalTab(state.meetingId);
|
||||
setTimeout(function() {
|
||||
$('#stream-box').style.display = 'none';
|
||||
$('#processing-indicator').style.display = 'none';
|
||||
state.processing = false;
|
||||
$('#btn-process').disabled = false;
|
||||
refresh();
|
||||
}, 600);
|
||||
if (evt.data && evt.data.result) {
|
||||
$('#result-md').innerHTML = marked.parse(evt.data.result);
|
||||
}
|
||||
} else if (evt.type === 'error') {
|
||||
es.close();
|
||||
toast('处理失败: ' + evt.data, 'err');
|
||||
$('#stream-box').style.display = 'none';
|
||||
$('#stream-content').textContent = '';
|
||||
setTimeout(function() {
|
||||
$('#processing-indicator').style.display = 'none';
|
||||
state.processing = false;
|
||||
$('#btn-process').disabled = false;
|
||||
}, 1500);
|
||||
}
|
||||
} catch(ex) {}
|
||||
};
|
||||
|
||||
es.onerror = function() {
|
||||
es.close();
|
||||
state.processing = false;
|
||||
$('#processing-indicator').style.display = 'none';
|
||||
$('#stream-box').style.display = 'none';
|
||||
$('#stream-content').textContent = '';
|
||||
$('#btn-process').disabled = false;
|
||||
if (!resultAcc) toast('连接中断', 'err');
|
||||
refresh();
|
||||
};
|
||||
});
|
||||
|
||||
// ─── Template ───
|
||||
function loadTemplate(name) {
|
||||
state.templateName = name;
|
||||
api('/api/templates/' + name).then(function(r) {
|
||||
state.editMode = false;
|
||||
$('#template-editor').value = r.content;
|
||||
$('#template-editor').style.display = 'none';
|
||||
$('#template-preview').style.display = 'block';
|
||||
$('#template-preview').innerHTML = marked.parse(r.content);
|
||||
$('#btn-toggle-edit').innerHTML = '✏ 编辑';
|
||||
var sel = $('#tpl-select');
|
||||
if (sel) sel.value = name;
|
||||
}).catch(function(e) { toast(e.message, 'err'); });
|
||||
}
|
||||
|
||||
$('#btn-toggle-edit').addEventListener('click', function() {
|
||||
state.editMode = !state.editMode;
|
||||
if (state.editMode) {
|
||||
$('#template-editor').style.display = 'block';
|
||||
$('#template-preview').style.display = 'none';
|
||||
$('#btn-toggle-edit').innerHTML = '👁 预览';
|
||||
} else {
|
||||
var content = $('#template-editor').value;
|
||||
$('#template-editor').style.display = 'none';
|
||||
$('#template-preview').style.display = 'block';
|
||||
$('#template-preview').innerHTML = marked.parse(content);
|
||||
$('#btn-toggle-edit').innerHTML = '✏ 编辑';
|
||||
api('/api/templates/' + state.templateName, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content: content }),
|
||||
}).catch(function(e) { toast('保存失败: ' + e.message, 'err'); });
|
||||
}
|
||||
});
|
||||
|
||||
$('#tpl-select').addEventListener('change', function() {
|
||||
state.templateName = this.value;
|
||||
loadTemplate(this.value);
|
||||
});
|
||||
|
||||
$('#panel-tabs').addEventListener('click', function(e) {
|
||||
var tab = e.target.closest('.tab');
|
||||
if (!tab) return;
|
||||
var tabName = tab.dataset.tab;
|
||||
|
||||
$$('#panel-tabs .tab').forEach(function(t) { t.classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
|
||||
if (tabName === 'template') {
|
||||
$('#template-tab').style.display = 'block';
|
||||
$('#original-tab').style.display = 'none';
|
||||
} else {
|
||||
$('#template-tab').style.display = 'none';
|
||||
$('#original-tab').style.display = 'block';
|
||||
if (state.meetingId) {
|
||||
loadOriginalContent(state.meetingId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function switchToOriginalTab(mid) {
|
||||
var ot = $$('#panel-tabs .tab[data-tab="original"]')[0];
|
||||
if (ot && !ot.classList.contains('active')) {
|
||||
ot.click();
|
||||
} else if (ot) {
|
||||
loadOriginalContent(mid);
|
||||
}
|
||||
}
|
||||
|
||||
function loadOriginalContent(mid) {
|
||||
api('/api/meetings/' + mid + '/transcript').then(function(r) {
|
||||
$('#original-content').textContent = r.content;
|
||||
}).catch(function() {
|
||||
$('#original-content').textContent = '(无法加载原文)';
|
||||
});
|
||||
}
|
||||
|
||||
// ─── Import ───
|
||||
$('#btn-import').addEventListener('click', function() {
|
||||
openModal('modal-import');
|
||||
$('#import-name').value = '';
|
||||
$('#import-file').value = '';
|
||||
});
|
||||
|
||||
$('#btn-confirm-import').addEventListener('click', function() {
|
||||
var name = $('#import-name').value.trim();
|
||||
var file = $('#import-file').files[0];
|
||||
if (!name) { toast('请输入会议名称', 'err'); return; }
|
||||
if (!file) { toast('请选择文件', 'err'); return; }
|
||||
|
||||
var fd = new FormData();
|
||||
fd.append('name', name);
|
||||
fd.append('file', file);
|
||||
|
||||
fetch('/api/meetings/import', { method: 'POST', body: fd }).then(function(r) {
|
||||
if (!r.ok) return r.json().then(function(e) { throw new Error(e.detail); });
|
||||
return r.json();
|
||||
}).then(function(d) {
|
||||
closeModal('modal-import');
|
||||
toast('导入成功: ' + d.name);
|
||||
refresh().then(function() { selectMeeting(d.id); });
|
||||
}).catch(function(e) { toast('导入失败: ' + e.message, 'err'); });
|
||||
});
|
||||
|
||||
document.getElementById('modal-import').addEventListener('click', function(e) {
|
||||
if (e.target === this) closeModal('modal-import');
|
||||
});
|
||||
document.getElementById('modal-settings').addEventListener('click', function(e) {
|
||||
if (e.target === this) closeModal('modal-settings');
|
||||
});
|
||||
|
||||
// ─── Settings ───
|
||||
$('#btn-settings').addEventListener('click', function() {
|
||||
api('/api/settings').then(function(cfg) {
|
||||
$('#cfg-url').value = cfg.api_base_url || '';
|
||||
$('#cfg-key').value = cfg.api_key || '';
|
||||
$('#cfg-model').value = cfg.model_name || '';
|
||||
openModal('modal-settings');
|
||||
}).catch(function() { openModal('modal-settings'); });
|
||||
});
|
||||
|
||||
$('#btn-save-settings').addEventListener('click', function() {
|
||||
var cfg = {
|
||||
api_base_url: $('#cfg-url').value.trim(),
|
||||
api_key: $('#cfg-key').value.trim(),
|
||||
model_name: $('#cfg-model').value.trim(),
|
||||
};
|
||||
api('/api/settings', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(cfg),
|
||||
}).then(function() {
|
||||
closeModal('modal-settings');
|
||||
toast('配置已保存');
|
||||
}).catch(function(e) { toast(e.message, 'err'); });
|
||||
});
|
||||
|
||||
// ─── Init ───
|
||||
function refresh() {
|
||||
return api('/api/templates').then(function(ts) {
|
||||
state.templates = ts;
|
||||
var sel = $('#tpl-select');
|
||||
sel.innerHTML = '';
|
||||
ts.forEach(function(t) {
|
||||
var o = document.createElement('option');
|
||||
o.value = t.name;
|
||||
o.textContent = t.name;
|
||||
sel.appendChild(o);
|
||||
});
|
||||
sel.value = state.templateName;
|
||||
}).then(function() {
|
||||
return api('/api/tree');
|
||||
}).then(function(tree) {
|
||||
buildTree(tree);
|
||||
});
|
||||
}
|
||||
|
||||
refresh().then(function() {
|
||||
loadTemplate(state.templateName);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue