|
@@ -76,22 +76,22 @@
|
|
|
<img class="vb-img1" :src="'https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/master/versionTwo/intro_box_img1.png'">
|
|
<img class="vb-img1" :src="'https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/master/versionTwo/intro_box_img1.png'">
|
|
|
<view class="v2-p2">报告的核心是PERILL评估分析下的整体团队表现。这包括团队在PERILL模型每个关键要素上的综合得分,通过结合得分和置信指数,我们能够展示出高功能和低功能领域。</view>
|
|
<view class="v2-p2">报告的核心是PERILL评估分析下的整体团队表现。这包括团队在PERILL模型每个关键要素上的综合得分,通过结合得分和置信指数,我们能够展示出高功能和低功能领域。</view>
|
|
|
<view class="v2-p2" style="margin-top: 2px;font-weight: 400;color: #002846;font-size: 10px;">下面图中的位置标记显示了团队按影响力划分的总分。</view>
|
|
<view class="v2-p2" style="margin-top: 2px;font-weight: 400;color: #002846;font-size: 10px;">下面图中的位置标记显示了团队按影响力划分的总分。</view>
|
|
|
- <view class="vb-category">
|
|
|
|
|
|
|
+ <view class="vb-category" v-if="reportData&&reportData.teamInfo">
|
|
|
<view class="vbc-pre adfac">
|
|
<view class="vbc-pre adfac">
|
|
|
<view class="vbcp-yuan y1"></view>
|
|
<view class="vbcp-yuan y1"></view>
|
|
|
- <view class="vbcp-text">团队领导者 Team Leader</view>
|
|
|
|
|
|
|
+ <view class="vbcp-text">团队领导者 Team Leader {{ reportData.teamInfo.leaderCount||0 }}人</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="vbc-pre adfac">
|
|
<view class="vbc-pre adfac">
|
|
|
<view class="vbcp-yuan y2"></view>
|
|
<view class="vbcp-yuan y2"></view>
|
|
|
- <view class="vbcp-text">团队成员 Team Member</view>
|
|
|
|
|
|
|
+ <view class="vbcp-text">团队成员 Team Member {{ reportData.teamInfo.memberCount||0 }}人</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="vbc-pre adfac">
|
|
<view class="vbc-pre adfac">
|
|
|
<view class="vbcp-yuan y3"></view>
|
|
<view class="vbcp-yuan y3"></view>
|
|
|
- <view class="vbcp-text">利益相关方 Stakeholder</view>
|
|
|
|
|
|
|
+ <view class="vbcp-text">利益相关方 Stakeholder {{ reportData.teamInfo.stackCount||0 }}人</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="vbc-pre adfac">
|
|
<view class="vbc-pre adfac">
|
|
|
<view class="vbcp-yuan y4"></view>
|
|
<view class="vbcp-yuan y4"></view>
|
|
|
- <view class="vbcp-text">赞助人/出资人 Sponsor</view>
|
|
|
|
|
|
|
+ <view class="vbcp-text">赞助人/出资人 Sponsor {{ reportData.teamInfo.sponsorCount||0 }}人</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view style="width:360px;height:360px;margin: 0 auto;" class="pdfEchart">
|
|
<view style="width:360px;height:360px;margin: 0 auto;" class="pdfEchart">
|
|
@@ -102,8 +102,40 @@
|
|
|
a.“认同度分”,指标逻辑为团队全体对当前主题所对应各问卷题目认同度评分的均值,用来表征团队对这一主题问卷所陈述内容与团队情况的相符合程度的平均认知,最高分:5分,最低分:1分;<br>
|
|
a.“认同度分”,指标逻辑为团队全体对当前主题所对应各问卷题目认同度评分的均值,用来表征团队对这一主题问卷所陈述内容与团队情况的相符合程度的平均认知,最高分:5分,最低分:1分;<br>
|
|
|
b.“重要分”,指标逻辑为根据团队全体对当前主题所对应各问卷题目重要性评分的均值,用来表征团队对这一主题问卷所陈述内容对于团队重要性的平均认知,最高分:5分,最低分:1分;<br>
|
|
b.“重要分”,指标逻辑为根据团队全体对当前主题所对应各问卷题目重要性评分的均值,用来表征团队对这一主题问卷所陈述内容对于团队重要性的平均认知,最高分:5分,最低分:1分;<br>
|
|
|
c.“影响力分”,指标逻辑为综合团队全体对当前主题所对应各问卷题目的认同度与重要性的评分数据测算而来,用来表征团队对这一主题问卷所陈述内容对于团队的影响力水平,最高分:5分,最低分:1分;</view>
|
|
c.“影响力分”,指标逻辑为综合团队全体对当前主题所对应各问卷题目的认同度与重要性的评分数据测算而来,用来表征团队对这一主题问卷所陈述内容对于团队的影响力水平,最高分:5分,最低分:1分;</view>
|
|
|
- <view class="v2b-title">评估结果</view>
|
|
|
|
|
- <view class="v2b-p" v-html="renderMarkdown(reportData.totalDiagnosticOutput||'')"></view>
|
|
|
|
|
|
|
+ <view class="v2b-title">总评分表</view>
|
|
|
|
|
+ <view class="sum_score_table">
|
|
|
|
|
+ <div class="sst-th adfac">
|
|
|
|
|
+ <div class="sstt1">PERILL纬度</div>
|
|
|
|
|
+ <div class="sstt2">
|
|
|
|
|
+ <div class="sstt2-title">团队全员</div>
|
|
|
|
|
+ <div class="sstt2-subs adfac">
|
|
|
|
|
+ <div class="sstt2-s sstt-td">认同度</div>
|
|
|
|
|
+ <div class="sstt2-s sstt-td">重要性</div>
|
|
|
|
|
+ <div class="sstt2-s sstt-td">影响力</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sstt3">
|
|
|
|
|
+ <div class="sstt3-pre adfac">
|
|
|
|
|
+ <div class="sstt-td">利益相关者</div>
|
|
|
|
|
+ <div class="sstt-td notr">赞助者</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sstt3-pre adfac">
|
|
|
|
|
+ <div class="sstt-td">影响力</div>
|
|
|
|
|
+ <div class="sstt-td notr">影响力</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="sst-trs">
|
|
|
|
|
+ <div class="sstr-pre adfac" :class="{'spbg':index%2===1,'lasttr':index===perillData.length-1}" v-for="(item,index) in perillData" :key="index">
|
|
|
|
|
+ <div class="sstr-td1">{{ item.dimension }}</div>
|
|
|
|
|
+ <div class="sstr-td2">{{ item.teamRecognition }}</div>
|
|
|
|
|
+ <div class="sstr-td2">{{ item.teamImportance }}</div>
|
|
|
|
|
+ <div class="sstr-td2">{{ item.teamInfluence }}</div>
|
|
|
|
|
+ <div class="sstr-td2">{{ item.stakeholderInfluence }}</div>
|
|
|
|
|
+ <div class="sstr-td2 notr">{{ item.sponsorInfluence }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
<!-- 总体评估分析 评估建议-->
|
|
<!-- 总体评估分析 评估建议-->
|
|
@@ -116,7 +148,8 @@
|
|
|
<img class="vb-img1" :src="'https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/master/versionTwo/intro_box_img1.png'">
|
|
<img class="vb-img1" :src="'https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/master/versionTwo/intro_box_img1.png'">
|
|
|
<view class="v2b-title" style="margin-top: 0;">评估建议</view>
|
|
<view class="v2b-title" style="margin-top: 0;">评估建议</view>
|
|
|
<view class="v2b-p" v-html="renderMarkdown(reportData.totalDiagnosisSuggest||'')"></view>
|
|
<view class="v2b-p" v-html="renderMarkdown(reportData.totalDiagnosisSuggest||'')"></view>
|
|
|
- <view class="v2b-alert">注:团队发展本身就不是单一答案的过程,PERILL AI教练根据创衡独创团队教练方法论,可以从不同角度解读团队,发现那些隐藏的机会点。多元建议代表多元可能。您可以尝试再次生成评估报告,探索更多可能性。</view>
|
|
|
|
|
|
|
+ <view class="v2b-title">评估结果</view>
|
|
|
|
|
+ <view class="v2b-p" v-html="renderMarkdown(reportData.totalDiagnosticOutput||'')"></view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
<!-- 多维度 -->
|
|
<!-- 多维度 -->
|
|
@@ -216,8 +249,12 @@
|
|
|
<view class="fdy-subtitle2">3. 如需深度支持,可考虑引入团队教练辅导助力团队发展</view>
|
|
<view class="fdy-subtitle2">3. 如需深度支持,可考虑引入团队教练辅导助力团队发展</view>
|
|
|
<view class="fdy-p">每一支高价值团队,都始于对现状清醒的认知与共同进化的勇气。PERILL为团队提供了导航仪与路线图——下一步,行动在您们手中。</view>
|
|
<view class="fdy-p">每一支高价值团队,都始于对现状清醒的认知与共同进化的勇气。PERILL为团队提供了导航仪与路线图——下一步,行动在您们手中。</view>
|
|
|
<view class="fdy-p">PERILL不止于评估,更在于赋能。期待与您和团队同行,见证未来的更多可能。</view>
|
|
<view class="fdy-p">PERILL不止于评估,更在于赋能。期待与您和团队同行,见证未来的更多可能。</view>
|
|
|
- <view class="fdy-p" style="margin-top: 41px;">具体需求可联系您的团队教练 或 扫码联系“⼤衡同学”。</view>
|
|
|
|
|
- <view class="fdy-code adfacjc"><img class="fdy-code-team" :src="'https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/master/versionTwo/fdy_code.png'"></view>
|
|
|
|
|
|
|
+ <view class="fdy-p" style="margin-top: 8px;">具体需求可联系您的团队教练 或 扫码联系“⼤衡同学”。</view>
|
|
|
|
|
+ <view class="fdy-code adffcac">
|
|
|
|
|
+ <img class="fdy-code-team" :src="'https://gitee.com/hw_0302/chuang-heng-wechat-images/raw/master/versionTwo/fdy_code.png'">
|
|
|
|
|
+ <p style="margin-top: 0;font-size: 10px;color: #002846;line-height: 18px;">扫码联系大衡同学</p>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="v2b-alert">注:团队发展本身就不是单一答案的过程,PERILL AI教练根据创衡独创团队教练方法论,可以从不同角度解读团队,发现那些隐藏的机会点。多元建议代表多元可能。您可以尝试再次生成评估报告,探索更多可能性。</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="pdf_btn" @click="createPdf">生成PDF</view>
|
|
<view class="pdf_btn" @click="createPdf">生成PDF</view>
|
|
@@ -244,12 +281,12 @@
|
|
|
scale:1,
|
|
scale:1,
|
|
|
originalContainerHeight: 0,
|
|
originalContainerHeight: 0,
|
|
|
containerScaledHeight: 'auto',
|
|
containerScaledHeight: 'auto',
|
|
|
- typeDict: {
|
|
|
|
|
- '宗旨与动机':'zzdj',
|
|
|
|
|
- '外部流程、系统与结构':'wbjg',
|
|
|
|
|
- '人际关系':'rjgx',
|
|
|
|
|
- '内部流程、系统与结构':'nbjg',
|
|
|
|
|
- '学习':'xx',
|
|
|
|
|
|
|
+ typeDict: {
|
|
|
|
|
+ '宗旨与动机':'zzdj',
|
|
|
|
|
+ '外部流程、系统与结构':'wbjg',
|
|
|
|
|
+ '人际关系':'rjgx',
|
|
|
|
|
+ '内部流程、系统与结构':'nbjg',
|
|
|
|
|
+ '学习':'xx',
|
|
|
'领导力':'ldl'
|
|
'领导力':'ldl'
|
|
|
},
|
|
},
|
|
|
sixWd: [
|
|
sixWd: [
|
|
@@ -297,6 +334,62 @@
|
|
|
}
|
|
}
|
|
|
],
|
|
],
|
|
|
pdfImages:[],
|
|
pdfImages:[],
|
|
|
|
|
+ perillData:[
|
|
|
|
|
+ {
|
|
|
|
|
+ filter: '宗旨与动机',
|
|
|
|
|
+ dimension: '宗旨与动机(P)',
|
|
|
|
|
+ teamRecognition: '-',
|
|
|
|
|
+ teamImportance: '-',
|
|
|
|
|
+ teamInfluence: '-',
|
|
|
|
|
+ stakeholderInfluence: '-',
|
|
|
|
|
+ sponsorInfluence: '-'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ filter: '外部流程、系统与结构',
|
|
|
|
|
+ dimension: '外部流程及系统及架构(E)',
|
|
|
|
|
+ teamRecognition: '-',
|
|
|
|
|
+ teamImportance: '-',
|
|
|
|
|
+ teamInfluence: '-',
|
|
|
|
|
+ stakeholderInfluence: '-',
|
|
|
|
|
+ sponsorInfluence: '-'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ filter: '人际关系',
|
|
|
|
|
+ dimension: '人际关系(R)',
|
|
|
|
|
+ teamRecognition: '-',
|
|
|
|
|
+ teamImportance: '-',
|
|
|
|
|
+ teamInfluence: '-',
|
|
|
|
|
+ stakeholderInfluence: '-',
|
|
|
|
|
+ sponsorInfluence: '-'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ filter: '内部流程、系统与结构',
|
|
|
|
|
+ dimension: '内部流程及系统及架构(I)',
|
|
|
|
|
+ teamRecognition: '-',
|
|
|
|
|
+ teamImportance: '-',
|
|
|
|
|
+ teamInfluence: '-',
|
|
|
|
|
+ stakeholderInfluence: '-',
|
|
|
|
|
+ sponsorInfluence: '-'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ filter: '学习',
|
|
|
|
|
+ dimension: '学习(L)',
|
|
|
|
|
+ teamRecognition: '-',
|
|
|
|
|
+ teamImportance: '-',
|
|
|
|
|
+ teamInfluence: '-',
|
|
|
|
|
+ stakeholderInfluence: '-',
|
|
|
|
|
+ sponsorInfluence: '-'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ filter: '领导力',
|
|
|
|
|
+ dimension: '领导力(L)',
|
|
|
|
|
+ teamRecognition: '-',
|
|
|
|
|
+ teamImportance: '-',
|
|
|
|
|
+ teamInfluence: '-',
|
|
|
|
|
+ stakeholderInfluence: '-',
|
|
|
|
|
+ sponsorInfluence: '-'
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
onLoad(options) {
|
|
onLoad(options) {
|
|
@@ -314,79 +407,92 @@
|
|
|
this.calculateScaleAndPosition();
|
|
this.calculateScaleAndPosition();
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
- methods: {
|
|
|
|
|
- renderMarkdown(val) {
|
|
|
|
|
- if(!val) return '';
|
|
|
|
|
- val = '<span style="padding-left:4ch;"></span>'+val;
|
|
|
|
|
- val = this.formattedText2(val);
|
|
|
|
|
- val = val.replaceAll('\n','<br><span style="padding-left:4ch;"></span>')
|
|
|
|
|
- val = this.formattedText(val);
|
|
|
|
|
- return val
|
|
|
|
|
- },
|
|
|
|
|
- renderMarkdown2(val) {
|
|
|
|
|
- if(!val) return '';
|
|
|
|
|
- val = '<span style="padding-left:4ch;"></span>'+val;
|
|
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ renderMarkdown(val) {
|
|
|
|
|
+ if(!val) return '';
|
|
|
|
|
+ val = '<span style="padding-left:4ch;"></span>'+val;
|
|
|
|
|
+ val = this.formattedText2(val);
|
|
|
val = val.replaceAll('\n','<br><span style="padding-left:4ch;"></span>')
|
|
val = val.replaceAll('\n','<br><span style="padding-left:4ch;"></span>')
|
|
|
- return val
|
|
|
|
|
- },
|
|
|
|
|
- formattedText(val) {
|
|
|
|
|
- // 正则表达式:匹配**包裹的内容
|
|
|
|
|
- // /\*\*(.*?)\*\*/g 解析:
|
|
|
|
|
- // \*\* 匹配两个星号(*需要转义)
|
|
|
|
|
- // (.*?) 非贪婪匹配任意字符(括号捕获匹配的内容)
|
|
|
|
|
- // g 全局匹配(替换所有符合条件的内容)
|
|
|
|
|
- const regex = /\*\*(.*?)\*\*/g
|
|
|
|
|
- // 替换为<b>标签,$1表示正则中括号捕获的内容
|
|
|
|
|
- return val.replace(regex, '<b>$1</b>')
|
|
|
|
|
- },
|
|
|
|
|
- formattedText2(val) {
|
|
|
|
|
- // 正则解析:
|
|
|
|
|
- // #{1,6} 匹配1到6个#
|
|
|
|
|
- // (.*?) 非贪婪捕获#后、空格前的任意文字(核心要保留的内容)
|
|
|
|
|
- // \s 匹配后面的空格(注意是单个空格,若要兼容多个空格可改为\s+)
|
|
|
|
|
- // g 全局匹配,替换所有符合条件的内容
|
|
|
|
|
- const regex = /#{1,6}\s*(.+?)\s*\n/g;
|
|
|
|
|
-
|
|
|
|
|
- // 替换规则:将匹配到的 "#文字 " / "##文字 " / "###文字 " 转为 "<b>文字</b>"
|
|
|
|
|
- return val.replace(regex, '<b>$1</b><br>')
|
|
|
|
|
|
|
+ val = this.formattedText(val);
|
|
|
|
|
+ return val
|
|
|
|
|
+ },
|
|
|
|
|
+ renderMarkdown2(val) {
|
|
|
|
|
+ if(!val) return '';
|
|
|
|
|
+ val = '<span style="padding-left:4ch;"></span>'+val;
|
|
|
|
|
+ val = val.replaceAll('\n','<br><span style="padding-left:4ch;"></span>')
|
|
|
|
|
+ return val
|
|
|
|
|
+ },
|
|
|
|
|
+ formattedText(val) {
|
|
|
|
|
+ // 正则表达式:匹配**包裹的内容
|
|
|
|
|
+ // /\*\*(.*?)\*\*/g 解析:
|
|
|
|
|
+ // \*\* 匹配两个星号(*需要转义)
|
|
|
|
|
+ // (.*?) 非贪婪匹配任意字符(括号捕获匹配的内容)
|
|
|
|
|
+ // g 全局匹配(替换所有符合条件的内容)
|
|
|
|
|
+ const regex = /\*\*(.*?)\*\*/g
|
|
|
|
|
+ // 替换为<b>标签,$1表示正则中括号捕获的内容
|
|
|
|
|
+ return val.replace(regex, '<b>$1</b>')
|
|
|
|
|
+ },
|
|
|
|
|
+ formattedText2(val) {
|
|
|
|
|
+ // 正则解析:
|
|
|
|
|
+ // #{1,6} 匹配1到6个#
|
|
|
|
|
+ // (.*?) 非贪婪捕获#后、空格前的任意文字(核心要保留的内容)
|
|
|
|
|
+ // \s 匹配后面的空格(注意是单个空格,若要兼容多个空格可改为\s+)
|
|
|
|
|
+ // g 全局匹配,替换所有符合条件的内容
|
|
|
|
|
+ const regex = /#{1,6}\s*(.+?)\s*\n/g;
|
|
|
|
|
+
|
|
|
|
|
+ // 替换规则:将匹配到的 "#文字 " / "##文字 " / "###文字 " 转为 "<b>文字</b>"
|
|
|
|
|
+ return val.replace(regex, '<b>$1</b><br>')
|
|
|
},
|
|
},
|
|
|
getReportData(){
|
|
getReportData(){
|
|
|
this.$api.get(`/core/report/previewReport/${this.reportId}`).then(async ({data:res})=>{
|
|
this.$api.get(`/core/report/previewReport/${this.reportId}`).then(async ({data:res})=>{
|
|
|
if(res.code!==0) return this.$showToast(res.msg)
|
|
if(res.code!==0) return this.$showToast(res.msg)
|
|
|
this.reportData = res.data;
|
|
this.reportData = res.data;
|
|
|
|
|
|
|
|
- const tempDimensionAnalysis = [
|
|
|
|
|
- {
|
|
|
|
|
- title:'宗旨与动机',thbgcolor:'#761E6A',thtextcolor:'#FFFFFF',titlecolor:'#761E6A',dimensionCode:"purpose",bordercolor:'#E4D2E1',
|
|
|
|
|
- desc:`「宗旨与动机」维度,我们旨在探究团队是否有清晰的存在理由和明确的方向,能够激发团队成员的动力并吸引他们的想象力,以及个人与集体的身份认同是否围绕共同的目标,并在实现目标的优先次序上达成一致。`
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title:'外部流程、系统与结构',thbgcolor:'#009191',thtextcolor:'#FFFFFF',titlecolor:'#009191',dimensionCode:"external",bordercolor:'#B3DEDE',
|
|
|
|
|
- desc:`「外部流程、系统与结构」维度,我们旨在探究团队如何与各种利益相关者互动,他们与团队的利益相关方各自如何寻求了解对方,以及现有系统和流程的有效性,以帮助管理不同利益相关者的期望和需求。`
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title:'人际关系',thbgcolor:'#FFD750',thtextcolor:'#002846',titlecolor:'#002846',dimensionCode:"relationship",bordercolor:'#FFEBA8',
|
|
|
|
|
- desc:`「人际关系」维度,我们旨在探究团队成员相互沟通交流的状态,团队成员的信任程度、尊重和关心的程度、心理安全度,以及团队成员之间的关系如何促进(或破坏)协作。`
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title:'内部流程、系统与结构',thbgcolor:'#4EB2B2',thtextcolor:'#FFFFFF',titlecolor:'#33A7A7',dimensionCode:"internal",bordercolor:'#B3DEDE',
|
|
|
|
|
- desc:`「内部流程、系统与结构」维度,我们旨在探究团队在管理工作任务和流程中如何平衡责任与自主权进行协作。主要关注团队应对变化时的敏捷程度、日常沟通方式以及内部决策过程的有效性。`
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title:'学习',thbgcolor:'#AFCDF5',thtextcolor:'#002846',titlecolor:'#002846',dimensionCode:"learning",bordercolor:'#C7DCF8',
|
|
|
|
|
- desc:`「学习」维度,我们旨在探究团队如何提高其绩效(完成当下的任务)、能力(提高技能和资源以处理明天的任务)和容量(⻓期的愿景,用更少的资源做更多的事情)以应对当前和未来的任务。同时还关注团队如何管理这些能力和提高效率。`
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- title:'领导力',thbgcolor:'#002846',thtextcolor:'#FFFFFF',titlecolor:'#002846',dimensionCode:"leadership",bordercolor:'#E6EAED',
|
|
|
|
|
- desc:`「领导力」维度,我们旨在探究团队领导者的素质和行为(包括但不限于正式与非正式的引导、赋能与责任承担方式)如何对团队功能和其他因素产生影响,以及这是积极的还是消极的。`
|
|
|
|
|
|
|
+ const tempDimensionAnalysis = [
|
|
|
|
|
+ {
|
|
|
|
|
+ title:'宗旨与动机',thbgcolor:'#761E6A',thtextcolor:'#FFFFFF',titlecolor:'#761E6A',dimensionCode:"purpose",bordercolor:'#E4D2E1',
|
|
|
|
|
+ desc:`「宗旨与动机」维度,我们旨在探究团队是否有清晰的存在理由和明确的方向,能够激发团队成员的动力并吸引他们的想象力,以及个人与集体的身份认同是否围绕共同的目标,并在实现目标的优先次序上达成一致。`
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title:'外部流程、系统与结构',thbgcolor:'#009191',thtextcolor:'#FFFFFF',titlecolor:'#009191',dimensionCode:"external",bordercolor:'#B3DEDE',
|
|
|
|
|
+ desc:`「外部流程、系统与结构」维度,我们旨在探究团队如何与各种利益相关者互动,他们与团队的利益相关方各自如何寻求了解对方,以及现有系统和流程的有效性,以帮助管理不同利益相关者的期望和需求。`
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title:'人际关系',thbgcolor:'#FFD750',thtextcolor:'#002846',titlecolor:'#002846',dimensionCode:"relationship",bordercolor:'#FFEBA8',
|
|
|
|
|
+ desc:`「人际关系」维度,我们旨在探究团队成员相互沟通交流的状态,团队成员的信任程度、尊重和关心的程度、心理安全度,以及团队成员之间的关系如何促进(或破坏)协作。`
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title:'内部流程、系统与结构',thbgcolor:'#4EB2B2',thtextcolor:'#FFFFFF',titlecolor:'#33A7A7',dimensionCode:"internal",bordercolor:'#B3DEDE',
|
|
|
|
|
+ desc:`「内部流程、系统与结构」维度,我们旨在探究团队在管理工作任务和流程中如何平衡责任与自主权进行协作。主要关注团队应对变化时的敏捷程度、日常沟通方式以及内部决策过程的有效性。`
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title:'学习',thbgcolor:'#AFCDF5',thtextcolor:'#002846',titlecolor:'#002846',dimensionCode:"learning",bordercolor:'#C7DCF8',
|
|
|
|
|
+ desc:`「学习」维度,我们旨在探究团队如何提高其绩效(完成当下的任务)、能力(提高技能和资源以处理明天的任务)和容量(⻓期的愿景,用更少的资源做更多的事情)以应对当前和未来的任务。同时还关注团队如何管理这些能力和提高效率。`
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title:'领导力',thbgcolor:'#002846',thtextcolor:'#FFFFFF',titlecolor:'#002846',dimensionCode:"leadership",bordercolor:'#E6EAED',
|
|
|
|
|
+ desc:`「领导力」维度,我们旨在探究团队领导者的素质和行为(包括但不限于正式与非正式的引导、赋能与责任承担方式)如何对团队功能和其他因素产生影响,以及这是积极的还是消极的。`
|
|
|
}
|
|
}
|
|
|
]
|
|
]
|
|
|
- this.reportData.dimensionAnalysis.forEach((d,i)=>{
|
|
|
|
|
- d.scoreSpreads.forEach(s=>{
|
|
|
|
|
- s.theme = s.theme.replaceAll(',',' ').replaceAll(',','');
|
|
|
|
|
- })
|
|
|
|
|
- let temp = tempDimensionAnalysis.find(t=>t.dimensionCode === d.dimensionCode)||{};
|
|
|
|
|
|
|
+ this.reportData.dimensionAnalysis.forEach((d,i)=>{
|
|
|
|
|
+ d.scoreSpreads.forEach(s=>{
|
|
|
|
|
+ s.theme = s.theme.replaceAll(',',' ').replaceAll(',','');
|
|
|
|
|
+ })
|
|
|
|
|
+ let temp = tempDimensionAnalysis.find(t=>t.dimensionCode === d.dimensionCode)||{};
|
|
|
this.reportData.dimensionAnalysis[i] = {...d,...temp}
|
|
this.reportData.dimensionAnalysis[i] = {...d,...temp}
|
|
|
|
|
+ })
|
|
|
|
|
+ this.reportData.overall.forEach(o=>{
|
|
|
|
|
+ let temp = this.perillData.find(t=>t.filter === o.dimension);
|
|
|
|
|
+ let ti = this.perillData.findIndex(t=>t.filter === o.dimension);
|
|
|
|
|
+ if(temp&&ti>-1){
|
|
|
|
|
+ if(o.dimensionTotalSpreads&&o.dimensionTotalSpreads.length){
|
|
|
|
|
+ this.perillData[ti].teamRecognition = o.dimensionTotalSpreads[0].all_agreement||'-';
|
|
|
|
|
+ this.perillData[ti].teamImportance = o.dimensionTotalSpreads[0].all_vital||'-';
|
|
|
|
|
+ this.perillData[ti].teamInfluence = o.dimensionTotalSpreads[0].all_score||'-';
|
|
|
|
|
+ this.perillData[ti].stakeholderInfluence = o.dimensionTotalSpreads[0].stakeholder_score||'-';
|
|
|
|
|
+ this.perillData[ti].sponsorInfluence = o.dimensionTotalSpreads[0].sponsor_score||'-';
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 【关键逻辑】在数据渲染后,开始预加载图片
|
|
// 【关键逻辑】在数据渲染后,开始预加载图片
|
|
@@ -493,16 +599,18 @@
|
|
|
})
|
|
})
|
|
|
try {
|
|
try {
|
|
|
const ztzdfxImgPromise = this.downloadZtzdfxImg();
|
|
const ztzdfxImgPromise = this.downloadZtzdfxImg();
|
|
|
|
|
+ const sumScoreTablePromise = this.generateSumScoreTableImage();
|
|
|
const dimensionImagePromises = this.reportData.dimensionAnalysis.map(d => {
|
|
const dimensionImagePromises = this.reportData.dimensionAnalysis.map(d => {
|
|
|
return this.generateScoreImage(d,d.scoreSpreads);
|
|
return this.generateScoreImage(d,d.scoreSpreads);
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const allImageUrls = await Promise.all([
|
|
const allImageUrls = await Promise.all([
|
|
|
ztzdfxImgPromise,
|
|
ztzdfxImgPromise,
|
|
|
|
|
+ sumScoreTablePromise,
|
|
|
...dimensionImagePromises
|
|
...dimensionImagePromises
|
|
|
]);
|
|
]);
|
|
|
this.pdfImages = allImageUrls;
|
|
this.pdfImages = allImageUrls;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
this.$api.post('/core/report/reportToPdf',{
|
|
this.$api.post('/core/report/reportToPdf',{
|
|
|
images:this.pdfImages,
|
|
images:this.pdfImages,
|
|
|
reportId:this.reportId
|
|
reportId:this.reportId
|
|
@@ -531,10 +639,10 @@
|
|
|
const headerHeight = 26;
|
|
const headerHeight = 26;
|
|
|
const rowHeight = 54;
|
|
const rowHeight = 54;
|
|
|
const totalHeight = headerHeight + rowHeight * scoreData.length;
|
|
const totalHeight = headerHeight + rowHeight * scoreData.length;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const leftColWidth = 280;
|
|
const leftColWidth = 280;
|
|
|
const rightColWidth = 308;
|
|
const rightColWidth = 308;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// --- 2. 获取 Canvas 节点 ---
|
|
// --- 2. 获取 Canvas 节点 ---
|
|
|
const query = uni.createSelectorQuery().in(this);
|
|
const query = uni.createSelectorQuery().in(this);
|
|
|
query.select('#score-canvas')
|
|
query.select('#score-canvas')
|
|
@@ -551,36 +659,36 @@
|
|
|
});
|
|
});
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const canvasNode = res[0].node;
|
|
const canvasNode = res[0].node;
|
|
|
const ctx = canvasNode.getContext('2d');
|
|
const ctx = canvasNode.getContext('2d');
|
|
|
const dpr = uni.getSystemInfoSync().pixelRatio;
|
|
const dpr = uni.getSystemInfoSync().pixelRatio;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// --- 3. 设置画布尺寸和缩放以适应高分屏 ---
|
|
// --- 3. 设置画布尺寸和缩放以适应高分屏 ---
|
|
|
canvasNode.width = canvasWidth * dpr;
|
|
canvasNode.width = canvasWidth * dpr;
|
|
|
canvasNode.height = totalHeight * dpr;
|
|
canvasNode.height = totalHeight * dpr;
|
|
|
ctx.scale(dpr, dpr);
|
|
ctx.scale(dpr, dpr);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// --- 4. 开始绘制 ---
|
|
// --- 4. 开始绘制 ---
|
|
|
// 绘制大背景
|
|
// 绘制大背景
|
|
|
ctx.fillStyle = '#FFFFFF';
|
|
ctx.fillStyle = '#FFFFFF';
|
|
|
ctx.fillRect(0, 0, canvasWidth, totalHeight);
|
|
ctx.fillRect(0, 0, canvasWidth, totalHeight);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// --- 5. 绘制表头 ---
|
|
// --- 5. 绘制表头 ---
|
|
|
// 左侧表头背景
|
|
// 左侧表头背景
|
|
|
ctx.fillStyle = dimensionData.thbgcolor;
|
|
ctx.fillStyle = dimensionData.thbgcolor;
|
|
|
ctx.fillRect(0, 0, leftColWidth, headerHeight);
|
|
ctx.fillRect(0, 0, leftColWidth, headerHeight);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 右侧表头背景
|
|
// 右侧表头背景
|
|
|
ctx.fillRect(leftColWidth, 0, rightColWidth, headerHeight);
|
|
ctx.fillRect(leftColWidth, 0, rightColWidth, headerHeight);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 左侧表头文字
|
|
// 左侧表头文字
|
|
|
ctx.fillStyle = dimensionData.thtextcolor;
|
|
ctx.fillStyle = dimensionData.thtextcolor;
|
|
|
ctx.font = 'bold 9px sans-serif';
|
|
ctx.font = 'bold 9px sans-serif';
|
|
|
ctx.textBaseline = 'middle';
|
|
ctx.textBaseline = 'middle';
|
|
|
ctx.textAlign = 'left';
|
|
ctx.textAlign = 'left';
|
|
|
ctx.fillText('主题', 15, headerHeight / 2);
|
|
ctx.fillText('主题', 15, headerHeight / 2);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 左侧表头分割线
|
|
// 左侧表头分割线
|
|
|
ctx.strokeStyle = 'rgba(255,255,255,0.24)';
|
|
ctx.strokeStyle = 'rgba(255,255,255,0.24)';
|
|
|
ctx.lineWidth = 1;
|
|
ctx.lineWidth = 1;
|
|
@@ -594,34 +702,34 @@
|
|
|
ctx.moveTo(leftColWidth, 0);
|
|
ctx.moveTo(leftColWidth, 0);
|
|
|
ctx.lineTo(leftColWidth, headerHeight);
|
|
ctx.lineTo(leftColWidth, headerHeight);
|
|
|
ctx.stroke();
|
|
ctx.stroke();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
ctx.textAlign = 'center';
|
|
ctx.textAlign = 'center';
|
|
|
ctx.fillText('影响力分', leftColWidth - 27, headerHeight / 2);
|
|
ctx.fillText('影响力分', leftColWidth - 27, headerHeight / 2);
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 右侧表头分割线
|
|
// 右侧表头分割线
|
|
|
ctx.beginPath();
|
|
ctx.beginPath();
|
|
|
ctx.moveTo(leftColWidth + rightColWidth / 2, 0);
|
|
ctx.moveTo(leftColWidth + rightColWidth / 2, 0);
|
|
|
ctx.lineTo(leftColWidth + rightColWidth / 2, headerHeight);
|
|
ctx.lineTo(leftColWidth + rightColWidth / 2, headerHeight);
|
|
|
ctx.stroke();
|
|
ctx.stroke();
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// 右侧表头文字
|
|
// 右侧表头文字
|
|
|
ctx.fillText('认同度分', leftColWidth + rightColWidth / 4, headerHeight / 2);
|
|
ctx.fillText('认同度分', leftColWidth + rightColWidth / 4, headerHeight / 2);
|
|
|
ctx.fillText('重要性分', leftColWidth + rightColWidth * 0.75, headerHeight / 2);
|
|
ctx.fillText('重要性分', leftColWidth + rightColWidth * 0.75, headerHeight / 2);
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
// --- 6. 循环绘制每一行 ---
|
|
// --- 6. 循环绘制每一行 ---
|
|
|
for (let i = 0; i < scoreData.length; i++) {
|
|
for (let i = 0; i < scoreData.length; i++) {
|
|
|
const item = scoreData[i];
|
|
const item = scoreData[i];
|
|
|
const yPos = headerHeight + i * rowHeight;
|
|
const yPos = headerHeight + i * rowHeight;
|
|
|
this.drawTableItem(ctx, item, yPos, leftColWidth, rightColWidth, rowHeight, dimensionData);
|
|
this.drawTableItem(ctx, item, yPos, leftColWidth, rightColWidth, rowHeight, dimensionData);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
// --- 7. 绘制最外层边框 ---
|
|
// --- 7. 绘制最外层边框 ---
|
|
|
ctx.strokeStyle = dimensionData.bordercolor;
|
|
ctx.strokeStyle = dimensionData.bordercolor;
|
|
|
ctx.lineWidth = 1;
|
|
ctx.lineWidth = 1;
|
|
|
ctx.strokeRect(0, 0, canvasWidth, totalHeight);
|
|
ctx.strokeRect(0, 0, canvasWidth, totalHeight);
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
// --- 9. 生成图片 ---
|
|
// --- 9. 生成图片 ---
|
|
|
uni.hideLoading();
|
|
uni.hideLoading();
|
|
|
uni.canvasToTempFilePath({
|
|
uni.canvasToTempFilePath({
|
|
@@ -649,6 +757,197 @@
|
|
|
});
|
|
});
|
|
|
})
|
|
})
|
|
|
},
|
|
},
|
|
|
|
|
+ // 绘制总评分表
|
|
|
|
|
+ async generateSumScoreTableImage() {
|
|
|
|
|
+ return new Promise(resolve => {
|
|
|
|
|
+ // --- 1. 定义尺寸和样式 ---
|
|
|
|
|
+ const canvasWidth = 588;
|
|
|
|
|
+ const headerHeight = 72;
|
|
|
|
|
+ const rowHeight = 36;
|
|
|
|
|
+ const totalHeight = headerHeight + rowHeight * this.perillData.length;
|
|
|
|
|
+
|
|
|
|
|
+ // 列宽设置
|
|
|
|
|
+ const colWidth = 87; // 标准列宽度
|
|
|
|
|
+ const col1Width = canvasWidth - colWidth * 5; // PERILL纬度列宽度
|
|
|
|
|
+
|
|
|
|
|
+ // --- 2. 获取 Canvas 节点 ---
|
|
|
|
|
+ const query = uni.createSelectorQuery().in(this);
|
|
|
|
|
+ query.select('#score-canvas')
|
|
|
|
|
+ .fields({
|
|
|
|
|
+ node: true,
|
|
|
|
|
+ size: true
|
|
|
|
|
+ })
|
|
|
|
|
+ .exec(async (res) => {
|
|
|
|
|
+ if (!res || !res[0] || !res[0].node) {
|
|
|
|
|
+ console.error('获取 Canvas 节点失败,请检查 canvas-id 和 type="2d" 是否正确设置。');
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '组件初始化失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const canvasNode = res[0].node;
|
|
|
|
|
+ const ctx = canvasNode.getContext('2d');
|
|
|
|
|
+ const dpr = uni.getSystemInfoSync().pixelRatio;
|
|
|
|
|
+
|
|
|
|
|
+ // --- 3. 设置画布尺寸和缩放以适应高分屏 ---
|
|
|
|
|
+ canvasNode.width = canvasWidth * dpr;
|
|
|
|
|
+ canvasNode.height = totalHeight * dpr;
|
|
|
|
|
+ ctx.scale(dpr, dpr);
|
|
|
|
|
+
|
|
|
|
|
+ // --- 4. 开始绘制 ---
|
|
|
|
|
+ // 绘制大背景
|
|
|
|
|
+ ctx.fillStyle = '#FFFFFF';
|
|
|
|
|
+ ctx.fillRect(0, 0, canvasWidth, totalHeight);
|
|
|
|
|
+
|
|
|
|
|
+ // --- 5. 绘制表头 ---
|
|
|
|
|
+ // 表头背景
|
|
|
|
|
+ ctx.fillStyle = '#F5F7F8';
|
|
|
|
|
+ ctx.fillRect(0, 0, canvasWidth, headerHeight);
|
|
|
|
|
+
|
|
|
|
|
+ // 表头文字样式
|
|
|
|
|
+ ctx.fillStyle = '#002846';
|
|
|
|
|
+ ctx.font = 'bold 12px PingFang-SC, sans-serif';
|
|
|
|
|
+ ctx.textBaseline = 'middle';
|
|
|
|
|
+
|
|
|
|
|
+ // 第一列:PERILL纬度
|
|
|
|
|
+ ctx.textAlign = 'left';
|
|
|
|
|
+ ctx.fillText('PERILL纬度', 10, headerHeight / 2);
|
|
|
|
|
+
|
|
|
|
|
+ // 第二列:团队全员
|
|
|
|
|
+ ctx.textAlign = 'center';
|
|
|
|
|
+ ctx.fillText('团队全员', col1Width + colWidth * 1.5, 18);
|
|
|
|
|
+
|
|
|
|
|
+ // 团队全员子列
|
|
|
|
|
+ ctx.font = 'bold 12px PingFang-SC, sans-serif';
|
|
|
|
|
+ ctx.fillText('认同度', col1Width + colWidth * 0.5, 54);
|
|
|
|
|
+ ctx.fillText('重要性', col1Width + colWidth * 1.5, 54);
|
|
|
|
|
+ ctx.fillText('影响力', col1Width + colWidth * 2.5, 54);
|
|
|
|
|
+
|
|
|
|
|
+ // 第三列:利益相关者
|
|
|
|
|
+ ctx.fillText('利益相关者', col1Width + colWidth * 3.5, 18);
|
|
|
|
|
+ ctx.fillText('影响力', col1Width + colWidth * 3.5, 54);
|
|
|
|
|
+
|
|
|
|
|
+ // 第四列:赞助者
|
|
|
|
|
+ ctx.fillText('赞助者', col1Width + colWidth * 4.5, 18);
|
|
|
|
|
+ ctx.fillText('影响力', col1Width + colWidth * 4.5, 54);
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制表头分割线
|
|
|
|
|
+ ctx.strokeStyle = '#AEDADA';
|
|
|
|
|
+ ctx.lineWidth = 1;
|
|
|
|
|
+
|
|
|
|
|
+ // 垂直线
|
|
|
|
|
+ ctx.beginPath();
|
|
|
|
|
+ // PERILL纬度列右边的线
|
|
|
|
|
+ ctx.moveTo(col1Width, 0);
|
|
|
|
|
+ ctx.lineTo(col1Width, headerHeight);
|
|
|
|
|
+ // 团队全员子列分割线(只在36px以下)
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth, 36);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth, headerHeight);
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth * 2, 36);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth * 2, headerHeight);
|
|
|
|
|
+ // 团队全员与利益相关者之间的线
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth * 3, 0);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth * 3, headerHeight);
|
|
|
|
|
+ // 利益相关者与赞助者之间的线
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth * 4, 0);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth * 4, headerHeight);
|
|
|
|
|
+ // 赞助者列右边的线
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth * 5, 0);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth * 5, headerHeight);
|
|
|
|
|
+ ctx.stroke();
|
|
|
|
|
+
|
|
|
|
|
+ // 水平线
|
|
|
|
|
+ ctx.beginPath();
|
|
|
|
|
+ // 只绘制PERILL纬度列右侧的横线
|
|
|
|
|
+ ctx.moveTo(col1Width, 36);
|
|
|
|
|
+ ctx.lineTo(canvasWidth, 36);
|
|
|
|
|
+ ctx.moveTo(0, headerHeight);
|
|
|
|
|
+ ctx.lineTo(canvasWidth, headerHeight);
|
|
|
|
|
+ ctx.stroke();
|
|
|
|
|
+
|
|
|
|
|
+ // --- 6. 绘制数据行 ---
|
|
|
|
|
+ ctx.font = 'bold 12px PingFang-SC, sans-serif';
|
|
|
|
|
+ ctx.textBaseline = 'middle';
|
|
|
|
|
+
|
|
|
|
|
+ for (let i = 0; i < this.perillData.length; i++) {
|
|
|
|
|
+ const item = this.perillData[i];
|
|
|
|
|
+ const yPos = headerHeight + i * rowHeight;
|
|
|
|
|
+
|
|
|
|
|
+ // 交替背景色
|
|
|
|
|
+ if (i % 2 === 1) {
|
|
|
|
|
+ ctx.fillStyle = 'rgba(51,167,167,0.08)';
|
|
|
|
|
+ ctx.fillRect(0, yPos, canvasWidth, rowHeight);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 第一列:维度名称
|
|
|
|
|
+ ctx.fillStyle = '#002846';
|
|
|
|
|
+ ctx.textAlign = 'left';
|
|
|
|
|
+ ctx.fillText(item.dimension, 10, yPos + rowHeight / 2);
|
|
|
|
|
+
|
|
|
|
|
+ // 其他列:数据
|
|
|
|
|
+ ctx.textAlign = 'center';
|
|
|
|
|
+ ctx.fillText(item.teamRecognition, col1Width + colWidth * 0.5, yPos + rowHeight / 2);
|
|
|
|
|
+ ctx.fillText(item.teamImportance, col1Width + colWidth * 1.5, yPos + rowHeight / 2);
|
|
|
|
|
+ ctx.fillText(item.teamInfluence, col1Width + colWidth * 2.5, yPos + rowHeight / 2);
|
|
|
|
|
+ ctx.fillText(item.stakeholderInfluence, col1Width + colWidth * 3.5, yPos + rowHeight / 2);
|
|
|
|
|
+ ctx.fillText(item.sponsorInfluence, col1Width + colWidth * 4.5, yPos + rowHeight / 2);
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制行分割线
|
|
|
|
|
+ if (i < this.perillData.length - 1) {
|
|
|
|
|
+ ctx.beginPath();
|
|
|
|
|
+ ctx.moveTo(0, yPos + rowHeight);
|
|
|
|
|
+ ctx.lineTo(canvasWidth, yPos + rowHeight);
|
|
|
|
|
+ ctx.stroke();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 绘制列分割线
|
|
|
|
|
+ ctx.beginPath();
|
|
|
|
|
+ ctx.moveTo(col1Width, yPos);
|
|
|
|
|
+ ctx.lineTo(col1Width, yPos + rowHeight);
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth, yPos);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth, yPos + rowHeight);
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth * 2, yPos);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth * 2, yPos + rowHeight);
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth * 3, yPos);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth * 3, yPos + rowHeight);
|
|
|
|
|
+ ctx.moveTo(col1Width + colWidth * 4, yPos);
|
|
|
|
|
+ ctx.lineTo(col1Width + colWidth * 4, yPos + rowHeight);
|
|
|
|
|
+ ctx.stroke();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // --- 7. 绘制最外层边框 ---
|
|
|
|
|
+ ctx.strokeStyle = '#AEDADA';
|
|
|
|
|
+ ctx.lineWidth = 1;
|
|
|
|
|
+ ctx.strokeRect(0, 0, canvasWidth, totalHeight);
|
|
|
|
|
+
|
|
|
|
|
+ // --- 8. 生成图片 ---
|
|
|
|
|
+ uni.canvasToTempFilePath({
|
|
|
|
|
+ canvas: canvasNode,
|
|
|
|
|
+ x: 0,
|
|
|
|
|
+ y: 0,
|
|
|
|
|
+ width: canvasWidth,
|
|
|
|
|
+ height: totalHeight,
|
|
|
|
|
+ destWidth: canvasWidth * dpr,
|
|
|
|
|
+ destHeight: totalHeight * dpr,
|
|
|
|
|
+ success: async (result) => {
|
|
|
|
|
+ console.log('总评分表图片生成成功!', result.tempFilePath);
|
|
|
|
|
+ const fileurl = await this.uploadFilePromise(result.tempFilePath);
|
|
|
|
|
+ console.log(fileurl, 'fileurl');
|
|
|
|
|
+ resolve(fileurl)
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: (err) => {
|
|
|
|
|
+ console.error('图片生成失败', err);
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: '图片生成失败',
|
|
|
|
|
+ icon: 'none'
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }, this);
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
drawTableItem(ctx, item, y, leftW, rightW, h, dimensionData) {
|
|
drawTableItem(ctx, item, y, leftW, rightW, h, dimensionData) {
|
|
|
// 1. 设置通用边框样式
|
|
// 1. 设置通用边框样式
|
|
|
ctx.strokeStyle = dimensionData.bordercolor;
|
|
ctx.strokeStyle = dimensionData.bordercolor;
|