TemplateDetails.vue 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445
  1. <template>
  2. <div class="box boxMinHeight">
  3. <header class="header">
  4. <div class="header-content flex-box-ce">
  5. <!-- 返回按钮 -->
  6. <div class="flex-box-ce header-left">
  7. <i class="el-icon-arrow-left fontColorC" @click="$router.go(-1)"></i>
  8. <div class="text fontColorB font-flex-word">{{ templateTitle }}</div>
  9. <i class="el-icon-edit" style="margin-left: 10px; color: #999;" @click="openEditDialog()"></i>
  10. </div>
  11. <!-- 教程指引 -->
  12. <div class="header-right">
  13. <el-tooltip effect="dark" content="教程指引" placement="top">
  14. <div class="icon flex-center-center" @click="initStepData()">
  15. <i class="el-icon-document"></i>
  16. </div>
  17. </el-tooltip>
  18. </div>
  19. </div>
  20. </header>
  21. <div style="height: 1px; background-color: #DCDFE6; margin-top: 5px;"></div>
  22. <el-alert class="bounce animated" type="warning" :title="alertTilte" :closable="false" show-icon
  23. style="width: 100%; margin-top: 10px;"></el-alert>
  24. <div class="flex-box-ce" style="justify-content: space-between; margin-top: 10px;">
  25. <div class="flex-box-ce">
  26. <el-button class="add-indicator-btn" type="primary" size="small" @click="addData()">添加指标</el-button>
  27. <el-button class="delete-indicator-btn" type="danger"
  28. :disabled="!(multipleSelection && multipleSelection.length > 0)" @click="confirmDelete()"
  29. size="small">批量删除</el-button>
  30. </div>
  31. <div class="flex-box-ce" style="padding: 0 20px; color: #999;">
  32. <el-popover placement="right" trigger="hover" class="popover" @show="showPopover">
  33. <div class="flex-box-ce" style="width: 200px; justify-content: space-between;">
  34. <el-checkbox v-model="checkAll" @change="checkAllChangeFn">全选</el-checkbox>
  35. <el-button type="text" @click="reset(true)">重置</el-button>
  36. </div>
  37. <div style="height: 1px; background-color: #DCDFE6; margin: 5px 0;"></div>
  38. <el-checkbox-group v-model="checkColumns" @change="changeColumns"
  39. style="width: 200px; display: flex; flex-direction: column;">
  40. <el-checkbox v-for="(item, key) in this.tableColumn" :label="item.label"
  41. :key="item.label"></el-checkbox>
  42. </el-checkbox-group>
  43. <div class="flex-box-ce" slot="reference">
  44. <el-button class="primaryBtn" icon="el-icon-s-tools" type="primary"
  45. size="mini">设置考核流程</el-button>
  46. </div>
  47. </el-popover>
  48. </div>
  49. </div>
  50. <div class="table-box">
  51. <el-table :data="tableData" v-loading="loading" stripe style="width: 100%; margin-top: 10px; height: auto;"
  52. border :header-cell-style="{ background: '#f5f7fa' }" @selection-change="handleSelectChange"
  53. row-key="indicatorId">
  54. <el-table-column type="selection"></el-table-column>
  55. <template v-for="item in tableColumn">
  56. <el-table-column v-if="item.isShow && item.label === '规则'" :key="item.prop" :prop="item.prop"
  57. :label="item.label" align="center" :min-width="item.width">
  58. <template slot-scope="scope">
  59. <el-tooltip v-if="scope.row.content" class="item" effect="dark" placement="top">
  60. <div v-html="scope.row.content" slot="content"
  61. style="max-width: 300px; white-space: pre-line;">
  62. </div>
  63. <div class="oneLine"
  64. @click="editContent(scope.$index, scope.row.content, scope.row.indicatorId)">
  65. {{ scope.row.content }}
  66. </div>
  67. </el-tooltip>
  68. <el-button v-else
  69. @click="editContent(scope.$index, scope.row.content, scope.row.indicatorId)">编辑规则</el-button>
  70. </template>
  71. </el-table-column>
  72. <el-table-column v-else-if="item.isShow && ['目标', '权重(%)'].includes(item.label)" :key="item.prop"
  73. :prop="item.prop" :label="item.label" align="center" :min-width="item.width">
  74. <template slot-scope="scope">
  75. <el-input v-model="scope.row[item.prop]" :placeholder="item.label" clearable
  76. @blur="handleEdit(item.prop, scope.row[item.prop], scope.row.indicatorId)"
  77. oninput="value=value.replace(/[^\d.]/g,'')"></el-input>
  78. </template>
  79. </el-table-column>
  80. <el-table-column v-else-if="item.isShow && item.label === '计算公式'" prop="formulae" label="计算公式"
  81. align="center" min-width="130">
  82. <template slot-scope="scope">
  83. <div class="formulas-setting">
  84. <el-button @click="openFormula(scope.row, scope.$index)">
  85. {{ scope.row.expression && scope.row.expression.formulas.length > 0 ? `公式
  86. ${scope.row.expression.formulas.length} 条` : '公式' }}
  87. </el-button>
  88. </div>
  89. </template>
  90. </el-table-column>
  91. <el-table-column v-else-if="item.isShow && item.label === '过程跟踪'" prop="okrs" label="过程跟踪"
  92. align="center" min-width="130">
  93. <template slot-scope="scope">
  94. <div class="formulas-setting">
  95. 1
  96. </div>
  97. </template>
  98. </el-table-column>
  99. <el-table-column v-else-if="item.isShow && ['指标', '单位'].includes(item.label)" :key="item.prop"
  100. :prop="item.prop" :label="item.label" align="center" :min-width="item.width">
  101. <template slot-scope="scope">
  102. <el-input v-model="scope.row[item.prop]" :placeholder="item.label" clearable
  103. @blur="handleEdit(item.prop, scope.row[item.prop], scope.row.indicatorId)"></el-input>
  104. </template>
  105. </el-table-column>
  106. <el-table-column v-if="item.isShow && flowColumn.includes(item.label)" :key="item.prop"
  107. :prop="item.prop" :label="item.label"
  108. :render-header="(h, obj) => renderHeader(h, item, item.prop)" align="center"
  109. :min-width="item.width" fixed="right">
  110. <template slot-scope="scope">
  111. <template v-if="item.label === '确认目标'">
  112. <el-switch v-if="!scope.row.flow.nodes[0].enable"
  113. :value="scope.row.flow.nodes[0].enable"
  114. @input="handleStatusChange(-1, scope.row, 'targetConfirms')"></el-switch>
  115. <ShowDataComp v-else-if="scope.row.flow.nodes[0].enable && isDataShow"
  116. :show-data="scope.row.flow.nodes[0]" :select-nodes="scope.row"
  117. @btnClick="handleBtnClick" />
  118. </template>
  119. <template v-if="item.label === '录入结果'">
  120. <el-switch v-if="!scope.row.flow.nodes[1].enable"
  121. :value="scope.row.flow.nodes[1].enable"
  122. @input="handleStatusChange(-1, scope.row, 'resultInput')"></el-switch>
  123. <ShowDataComp v-else-if="scope.row.flow.nodes[1].enable && isDataShow"
  124. :show-data="scope.row.flow.nodes[1]" :select-nodes="scope.row"
  125. @btnClick="handleBtnClick" />
  126. </template>
  127. <template v-if="item.label === '自评'">
  128. <el-switch :value="scope.row.flow.nodes[2].enable" @input="handleStatusChange(-1, scope.row, 'scoreSelf')"></el-switch>
  129. </template>
  130. <template v-if="item.label === '互评'">
  131. <el-switch :value="scope.row.flow.nodes[3].enable" @input="handleStatusChange(-1, scope.row, 'scoreEachOther')"></el-switch>
  132. </template>
  133. <template v-if="item.label === '评分'">
  134. <el-switch v-if="!scope.row.flow.nodes[4].enable"
  135. :value="scope.row.flow.nodes[4].enable"
  136. @input="handleStatusChange(-1, scope.row, 'scores')"></el-switch>
  137. <ShowDataComp v-else-if="scope.row.flow.nodes[4].enable && isDataShow"
  138. :show-data="scope.row.flow.nodes[4]" :select-nodes="scope.row"
  139. @btnClick="handleBtnClick" />
  140. </template>
  141. <template v-if="item.label === '审批'">
  142. <el-switch v-if="!scope.row.flow.nodes[5].enable"
  143. :value="scope.row.flow.nodes[5].enable"
  144. @input="handleStatusChange(-1, scope.row, 'reviews')"></el-switch>
  145. <ShowDataComp v-else-if="scope.row.flow.nodes[5].enable && isDataShow"
  146. :show-data="scope.row.flow.nodes[5]" :select-nodes="scope.row"
  147. @btnClick="handleBtnClick" />
  148. </template>
  149. <template v-if="item.label === '抄送'">
  150. <el-switch v-if="!scope.row.flow.nodes[6].enable"
  151. :value="scope.row.flow.nodes[6].enable"
  152. @input="handleStatusChange(-1, scope.row, 'cc')"></el-switch>
  153. <ShowDataComp v-else-if="scope.row.flow.nodes[6].enable && isDataShow"
  154. :show-data="scope.row.flow.nodes[6]" :select-nodes="scope.row"
  155. @btnClick="handleBtnClick" />
  156. </template>
  157. </template>
  158. </el-table-column>
  159. </template>
  160. </el-table>
  161. <div style="height: 50px;"></div>
  162. </div>
  163. <!-- <TiptapComp /> -->
  164. <!-- 编辑流程节点 -->
  165. <!-- <HandleNode v-if="currentIndicator" v-model="dialogVisible" :form-label="formLabel" :dialog-title="dialogTitle"
  166. :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
  167. :indicator-id="selectIndicatorId" @closeDialog="closeDialog" :tag-index="tagIndex"
  168. @onConfirm="finishHandle" /> -->
  169. <!-- 发布考核弹框 -->
  170. <PublishComp v-if="showPublish" v-model="showPublish" :template-ids="[templateId]"
  171. @onConfirm="onPubishConfirm" />
  172. <!-- 编辑计算公式 -->
  173. <FormulaComp v-if="showFormula" v-model="showFormula"
  174. :fixed-props="[{ key: 'target', name: '目标' }, { key: 'weight', name: '权重' }, { key: 'result', name: '结果值' }]"
  175. :expressions-props="currentIndicator.expression.formulas || []" @onConfirm="onFormulaConfirm" />
  176. <!-- 编辑规则 -->
  177. <EditContentComp v-if="showEditContent" v-model="showEditContent" :content="content"
  178. :indicator-id="selectIndicatorId" :template-id="templateId" @finishEdit="finishEditContent" />
  179. <!-- 批量修改流程节点 -->
  180. <BatchHandleNode v-if="batchHandleDialog" v-model="batchHandleDialog" :template-id="templateId"
  181. :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType" :handle-node="handleNode"
  182. @onConfirm="finishBatchHandle" />
  183. <!-- 编辑确认目标节点 -->
  184. <TargetConfirms v-if="targetConfirms" v-model="targetConfirms" :form-label="formLabel"
  185. :dialog-title="dialogTitle" :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
  186. :indicator-id="selectIndicatorId" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
  187. @onConfirm="finishHandle" />
  188. <!-- 编辑录入结果节点 -->
  189. <ResultInput v-if="resultInput" v-model="resultInput" :form-label="formLabel" :dialog-title="dialogTitle"
  190. :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
  191. :indicator-id="selectIndicatorId" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
  192. @onConfirm="finishHandle" />
  193. <!-- 编辑自评节点 -->
  194. <ScoreSelf v-if="scoreSelf" v-model="scoreSelf" :form-label="formLabel" :dialog-title="dialogTitle"
  195. :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
  196. :indicator-id="selectIndicatorId" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
  197. @onConfirm="finishHandle" />
  198. <!-- 编辑互评节点 -->
  199. <ScoreEachOther v-if="scoreEachOther" v-model="scoreEachOther" :form-label="formLabel"
  200. :dialog-title="dialogTitle" :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
  201. :indicator-id="selectIndicatorId" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
  202. @onConfirm="finishHandle" />
  203. <!-- 编辑评分节点 -->
  204. <Scores v-if="scores" v-model="scores" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
  205. :template-id="templateId" :select-nodes="selectNodes" :indicator-id="selectIndicatorId"
  206. @closeDialog="closeNodeDialog" :tag-index="tagIndex" @onConfirm="finishHandle" />
  207. <!-- 编辑审批节点 -->
  208. <Reviews v-if="reviews" v-model="reviews" :form-label="formLabel" :dialog-title="dialogTitle"
  209. :node-type="nodeType" :template-id="templateId" :select-nodes="selectNodes"
  210. :indicator-id="selectIndicatorId" @closeDialog="closeNodeDialog" :tag-index="tagIndex"
  211. @onConfirm="finishHandle" />
  212. <!-- 编辑审批节点 -->
  213. <CC v-if="cc" v-model="cc" :form-label="formLabel" :dialog-title="dialogTitle" :node-type="nodeType"
  214. :template-id="templateId" :select-nodes="selectNodes" :indicator-id="selectIndicatorId"
  215. @closeDialog="closeNodeDialog" :tag-index="tagIndex" @onConfirm="finishHandle" />
  216. <el-dialog title="编辑标题" center :visible.sync="editTitleDialogVisible" width="30%">
  217. <el-input v-model="title" placeholder="请输入模板名称" size="small"></el-input>
  218. <span slot="footer" class="dialog-footer">
  219. <el-button @click="editTitleDialogVisible = false">取 消</el-button>
  220. <el-button type="primary" @click="editTitle()">确 定</el-button>
  221. </span>
  222. </el-dialog>
  223. </div>
  224. </template>
  225. <script>
  226. import { mapGetters } from 'vuex';
  227. import FormulaComp from '@/newPerformance/components/TemplateDetails/FormulaComp'; // 计算公式弹框
  228. import HandleNode from '@/newPerformance/components/TemplateDetails/HandleNode'; //单独设置流程节点弹框
  229. import PublishComp from '@/newPerformance/components/TemplateDetails/PublishComp'; // 发布考核弹框
  230. import ShowDataComp from '@/newPerformance/components/PublicComp/ShowData'; // 显示节点数据组件
  231. import EditContentComp from '@/newPerformance/components/TemplateDetails/EditContent'; // 编辑规则组件
  232. import BatchHandleNode from '@/newPerformance/components/TemplateDetails/BatchHandleNode'; // 批量设置流程节点
  233. import TargetConfirms from '@/newPerformance/components/TemplateDetails/TargetConfirms'; // 确认目标流程节点
  234. import ResultInput from '@/newPerformance/components/TemplateDetails/ResultInput'; // 结果录入流程节点
  235. import ScoreSelf from '@/newPerformance/components/TemplateDetails/ScoreSelf'; // 自评流程节点
  236. import ScoreEachOther from '@/newPerformance/components/TemplateDetails/ScoreEachOther'; // 互评流程节点
  237. import Scores from '@/newPerformance/components/TemplateDetails/Scores'; // 评分流程节点
  238. import Reviews from '@/newPerformance/components/TemplateDetails/Reviews'; // 审批流程节点
  239. import CC from '@/newPerformance/components/TemplateDetails/CC'; // 审批流程节点
  240. import introJs from 'intro.js'
  241. import 'intro.js/introjs.css'
  242. import templateDetailsStep from "@/newPerformance/utils/templateDetailsStep"
  243. import Sortable from 'sortablejs';
  244. export default {
  245. components: {
  246. HandleNode,
  247. FormulaComp,
  248. PublishComp,
  249. ShowDataComp,
  250. EditContentComp,
  251. BatchHandleNode,
  252. TargetConfirms,
  253. ResultInput,
  254. ScoreSelf,
  255. ScoreEachOther,
  256. Scores,
  257. Reviews,
  258. CC
  259. },
  260. data() {
  261. return {
  262. isDataShow: false,
  263. isShow: false,
  264. templateTitle: "模板名称",
  265. loading: false,
  266. title: "模板名称",
  267. alertTilte: "可在表格中直接编辑指标,规则 (规则支持富文本) ,目标,单位,权重,计算公式以及流程节点, 注意: 每个指标的标题不能为空!每个指标的评分节点一定要开启!",
  268. templateId: "", // 模板ID
  269. tableData: [], // 表格数据
  270. showFormula: false, // 编辑计算公式弹框显示
  271. showPublish: false, // 发布考核弹框显示
  272. dialogVisible: false, // 编辑流程节点弹框显示
  273. editTitleDialogVisible: false,
  274. dialogTitle: "", // 编辑流程节点弹框标题
  275. isDisable: false, // 是否禁用
  276. nodeType: "", // 节点类型
  277. currentIndicator: null, // 操作的指标
  278. selectIndicatorId: "", // 选择的指标ID
  279. selectNodes: [], // 选中指标所有的节点
  280. selectIndex: 0, // 表格行索引
  281. formLabel: "",
  282. tagIndex: 0,
  283. multipleSelection: [],
  284. content: "", // 指标规则
  285. showEditContent: false, // 编辑指标内容弹框
  286. deptList: [], // 部门列表 - 树形结构
  287. dept_list: [], // 部门列表
  288. postList: [], // 岗位列表
  289. flowColumn: ["确认目标", "录入结果", "自评", "互评", "评分", "审批", "抄送"],
  290. tableColumn: [
  291. { label: "指标", prop: "title", isShow: true, width: 150 },
  292. { label: "规则", prop: "content", isShow: true, width: 150 },
  293. { label: "目标", prop: "target", isShow: true, width: 80 },
  294. { label: "单位", prop: "unit", isShow: true, width: 80 },
  295. { label: "权重(%)", prop: "weight", isShow: true, width: 80 },
  296. { label: "计算公式", prop: "formulae", isShow: true, width: 120 },
  297. // { label: "过程跟踪", prop: "okrs", isShow: true, width: 120 },
  298. { label: "录入结果", prop: "resultInput", isShow: false, width: 100 },
  299. { label: "自评", prop: "scoreSelf", isShow: false, width: 100 },
  300. { label: "互评", prop: "scoreEachOther", isShow: false, width: 100 },
  301. { label: "评分", prop: "scores", isShow: false, width: 100 },
  302. { label: "审批", prop: "reviews", isShow: false, width: 100 },
  303. { label: "抄送", prop: "cc", isShow: false, width: 100 }
  304. ],
  305. checkColumns: [],
  306. checkAll: false,
  307. flowInfo: {},
  308. handleNode: {},
  309. batchHandleDialog: false,
  310. targetConfirms: false,
  311. resultInput: false,
  312. scoreSelf: false,
  313. scoreEachOther: false,
  314. scores: false,
  315. reviews: false,
  316. cc: false
  317. }
  318. },
  319. computed: {
  320. ...mapGetters(['user_info']),
  321. // 指标标题为空不能发起考核
  322. isTitleNull() {
  323. return this.tableData.find(item => item.title == '' || item.title == null) ? true : false
  324. },
  325. // 指标评分为禁用不能发起考核
  326. isScoreNull() {
  327. return this.tableData.find(item => !item.flow.nodes[4].enable) ? true : false
  328. }
  329. },
  330. mounted() {
  331. },
  332. created() {
  333. this.initData();
  334. this.$nextTick(() => {
  335. this.rowDrop(); // 行拖拽
  336. this.columnDrop(); // 列拖拽
  337. })
  338. },
  339. methods: {
  340. initData() {
  341. this.tableColumn = [
  342. { label: "指标", prop: "title", isShow: true, width: 150 },
  343. { label: "规则", prop: "content", isShow: true, width: 150 },
  344. { label: "目标", prop: "target", isShow: true, width: 80 },
  345. { label: "单位", prop: "unit", isShow: true, width: 80 },
  346. { label: "权重(%)", prop: "weight", isShow: true, width: 80 },
  347. { label: "计算公式", prop: "formulae", isShow: true, width: 120 },
  348. // { label: "过程跟踪", prop: "okrs", isShow: true, width: 120 },
  349. { label: "确认目标", prop: "targetConfirms", isShow: false, width: 100 },
  350. { label: "录入结果", prop: "resultInput", isShow: false, width: 100 },
  351. { label: "自评", prop: "scoreSelf", isShow: false, width: 100 },
  352. { label: "互评", prop: "scoreEachOther", isShow: false, width: 100 },
  353. { label: "评分", prop: "scores", isShow: false, width: 100 },
  354. { label: "审批", prop: "reviews", isShow: false, width: 100 },
  355. { label: "抄送", prop: "cc", isShow: false, width: 100 }
  356. ]
  357. this.templateId = this.$route.params.templateDetailId;
  358. this.get_template_detail();
  359. this.get_table_data();
  360. this.isDataShow = false
  361. // 请求岗位列表,部门列表
  362. Promise.all([this.get_dept_list(), this.get_post_list()]).then(([deptRes, postRes]) => {
  363. if (deptRes.data.code !== 1) return this.$message.error(deptRes.data.msg || "请求部门列表数据出错")
  364. if (postRes.data.code !== 1) return this.$message.error(postRes.data.msg || "请求岗位列表数据出错")
  365. this.dept_list = deptRes.data.data.list;
  366. this.deptList = this.getTreeData(this.dept_list); // 处理成树状结构
  367. this.postList = postRes.data.data.list
  368. localStorage.setItem("dept_list", JSON.stringify(this.dept_list))
  369. localStorage.setItem("deptList", JSON.stringify(this.deptList))
  370. localStorage.setItem("postList", JSON.stringify(this.postList))
  371. this.isDataShow = true
  372. })
  373. },
  374. // 开启指引,需要静态数据
  375. initStepData() {
  376. this.tableColumn = [
  377. { label: "指标", prop: "title", isShow: true, width: 150 },
  378. { label: "规则", prop: "content", isShow: true, width: 150 },
  379. { label: "目标", prop: "target", isShow: true, width: 80 },
  380. { label: "单位", prop: "unit", isShow: true, width: 80 },
  381. { label: "权重(%)", prop: "weight", isShow: true, width: 80 },
  382. { label: "计算公式", prop: "formulae", isShow: true, width: 120 },
  383. // { label: "过程跟踪", prop: "okrs", isShow: true, width: 120 },
  384. { label: "确认目标", prop: "targetConfirms", isShow: true, width: 100 },
  385. { label: "录入结果", prop: "resultInput", isShow: true, width: 100 },
  386. { label: "自评", prop: "scoreSelf", isShow: true, width: 100 },
  387. { label: "互评", prop: "scoreEachOther", isShow: true, width: 100 },
  388. { label: "评分", prop: "scores", isShow: true, width: 100 },
  389. { label: "审批", prop: "reviews", isShow: true, width: 100 },
  390. { label: "抄送", prop: "cc", isShow: true, width: 100 }
  391. ]
  392. this.tableData = [
  393. {
  394. indicatorId: 13, templateId: 3, title: '业绩考核', content: "业绩每月达成10万", target: 10, unit: "万", weight: 10, expression: { formulas: [] },
  395. flow: {
  396. nodes: [{
  397. id: "TCS_1921125472071749634",
  398. allows: [],
  399. assigneeIds: [],
  400. assigneeType: [],
  401. children: [{
  402. allows: [],
  403. assigneeIds: [],
  404. assigneeType: "self",
  405. children: [],
  406. enable: true,
  407. id: "TC_1921125472071749635",
  408. leaderLevel: 1,
  409. multipleType: "or",
  410. type: "targetConfirm",
  411. weight: 0
  412. }],
  413. enable: true,
  414. leaderLevel: 1,
  415. multipleType: "or",
  416. type: "targetConfirms",
  417. weight: 0
  418. },
  419. {
  420. id: "RI_1921125472071749636",
  421. allows: ['transfer'],
  422. assigneeIds: [],
  423. assigneeType: 'self',
  424. enable: true,
  425. leaderLevel: 1,
  426. multipleType: "or",
  427. type: "resultInput",
  428. weight: 0
  429. },
  430. {
  431. id: "SELF_1921125472071749637",
  432. allows: [],
  433. assigneeIds: [],
  434. assigneeType: 'self',
  435. enable: true,
  436. leaderLevel: 1,
  437. multipleType: "or",
  438. type: "selfScore",
  439. weight: 0
  440. },
  441. {
  442. id: "EO_1921125472071749638",
  443. allows: [],
  444. assigneeIds: [],
  445. assigneeType: 'self',
  446. enable: true,
  447. leaderLevel: 1,
  448. multipleType: "or",
  449. type: "scoreEachOther",
  450. weight: 0
  451. },
  452. {
  453. id: "SS_1921125472071749634",
  454. allows: [],
  455. assigneeIds: [],
  456. assigneeType: [],
  457. children: [{
  458. allows: [],
  459. assigneeIds: [],
  460. assigneeType: "self",
  461. children: [],
  462. enable: true,
  463. id: "TC_1921125472071749635",
  464. leaderLevel: 1,
  465. multipleType: "or",
  466. type: "targetConfirm",
  467. weight: 0
  468. }],
  469. enable: true,
  470. leaderLevel: 1,
  471. multipleType: "or",
  472. type: "scrores",
  473. weight: 0
  474. },
  475. {
  476. id: "TCS_1921125472071749634",
  477. allows: [],
  478. assigneeIds: [],
  479. assigneeType: [],
  480. children: [{
  481. allows: [],
  482. assigneeIds: [],
  483. assigneeType: "self",
  484. children: [],
  485. enable: true,
  486. id: "TC_1921125472071749635",
  487. leaderLevel: 1,
  488. multipleType: "or",
  489. type: "targetConfirm",
  490. weight: 0
  491. }],
  492. enable: true,
  493. leaderLevel: 1,
  494. multipleType: "or",
  495. type: "targetConfirms",
  496. weight: 0
  497. },
  498. {
  499. id: "TCS_1921125472071749634",
  500. allows: [],
  501. assigneeIds: [],
  502. assigneeType: [],
  503. children: [{
  504. allows: [],
  505. assigneeIds: [],
  506. assigneeType: "self",
  507. children: [],
  508. enable: true,
  509. id: "TC_1921125472071749635",
  510. leaderLevel: 1,
  511. multipleType: "or",
  512. type: "targetConfirm",
  513. weight: 0
  514. }],
  515. enable: true,
  516. leaderLevel: 1,
  517. multipleType: "or",
  518. type: "targetConfirms",
  519. weight: 0
  520. },
  521. ]
  522. }
  523. }
  524. ]
  525. setTimeout(() => {
  526. this.startGuide();
  527. }, 300)
  528. },
  529. startGuide() {
  530. introJs().setOptions({
  531. nextLabel: '下一个', // 下一个按钮文字
  532. prevLabel: '上一个', // 上一个按钮文字
  533. skipLabel: '跳过', // 跳过按钮文字
  534. doneLabel: '立即体验',// 完成按钮文字
  535. tooltipClass: 'intro-tooltip', /* 引导说明文本框的样式 */
  536. highlightClass: 'intro-highlight', /* 说明高亮区域的样式 */
  537. exitOnEsc: true, /* 是否使用键盘Esc退出 */
  538. exitOnOverlayClick: false, /* 是否允许点击空白处退出 */
  539. keyboardNavigation: true, /* 是否允许键盘来操作 */
  540. showBullets: false, /* 是否使用点显示进度 */
  541. showProgress: false, /* 是否显示进度条 */
  542. scrollToElement: true, /* 是否滑动到高亮的区域 */
  543. overlayOpacity: 0.5, // 遮罩层的透明度 0-1之间
  544. positionPrecedence: ['bottom', 'top', 'right', 'left'], /* 当位置选择自动的时候,位置排列的优先级 */
  545. disableInteraction: false, /* 是否禁止与元素的相互关联 */
  546. hidePrev: true, /* 是否在第一步隐藏上一步 */
  547. hidePrev: false, // 在第一步中是否隐藏上一个按钮
  548. hideNext: false, // 在最后一步中是否隐藏下一个按钮
  549. exitOnOverlayClick: false, // 点击叠加层时是否退出介绍
  550. showStepNumbers: false, // 是否显示红色圆圈的步骤编号
  551. disableInteraction: true, // 是否禁用与突出显示的框内的元素的交互,就是禁止点击
  552. showBullets: true, // 是否显示面板指示点
  553. // 配置内容 steps数组,内部一个对象代表一个步骤
  554. steps: templateDetailsStep
  555. }).onbeforechange((e) => {
  556. // console.log(e)
  557. // if (e.className.includes("primaryBtn")) {
  558. // // this.$refs.UploadPublish2.openTemplate()
  559. // this.showPopover()
  560. // this.checkAllChangeFn(true)
  561. // }
  562. }).onexit((e) => {
  563. console.log("退出")
  564. this.initData()
  565. }).oncomplete((e) => {
  566. console.log("完成")
  567. this.initData()
  568. }).start()
  569. },
  570. // 行拖拽
  571. rowDrop() {
  572. // 要侦听拖拽响应的DOM对象(数据存储在.el-table__body-wrapper > .el-table__row > tbody标签中(el-table的数据部分的“最外层”class名为el-table__body-wrapper))
  573. const tbody = document.querySelector('.el-table__body-wrapper tbody');
  574. const that = this;
  575. if (tbody) {
  576. Sortable.create(tbody, {
  577. // 结束拖拽后的回调函数
  578. onEnd({ newIndex, oldIndex }) {
  579. console.log('拖动了行,序号(index)"' + oldIndex + '"拖动到序号(index)"' + newIndex + '"');
  580. const currentRow = that.tableData.splice(oldIndex, 1)[0]; // 将oldIndex位置的数据删除并取出,oldIndex后面位置的数据会依次前移一位
  581. that.tableData.splice(newIndex, 0, currentRow); // 将被删除元素插入到新位置(currRow表示上面的被删除数据)
  582. }
  583. })
  584. }
  585. },
  586. // 列拖拽
  587. columnDrop() {
  588. // 要侦听拖拽响应的DOM对象
  589. const wrapperTr = document.querySelector('.el-table__body-wrapper tr');
  590. const that = this;
  591. if (wrapperTr) {
  592. Sortable.create(wrapperTr, {
  593. animation: 180,
  594. delay: 0,
  595. // 结束拖拽后的回调函数
  596. onEnd: evt => {
  597. console.log('拖动了列(index):');
  598. const oldItem = that.dropCol[evt.oldIndex];
  599. that.dropCol.splice(evt.oldIndex, 1);
  600. that.dropCol.splice(evt.newIndex, 0, oldItem);
  601. }
  602. })
  603. }
  604. },
  605. openEditDialog() {
  606. this.editTitleDialogVisible = true
  607. },
  608. // 处理部门树状结构数据
  609. getTreeData(data) {
  610. for (var i = 0; i < data.length; i++) {
  611. data[i].checked = false;
  612. if (data[i].children.length < 1) {
  613. // children若为空数组,则将children设为undefined
  614. data[i].children = undefined;
  615. } else {
  616. // children若不为空数组,则继续 递归调用 本方法
  617. this.getTreeData(data[i].children);
  618. }
  619. }
  620. return data;
  621. },
  622. // 获取部门
  623. get_dept_list() {
  624. return this.$axiosUser('get', '/api/pro/department/tree', '', 'v2')
  625. },
  626. // 岗位列表
  627. get_post_list() {
  628. let data = {
  629. page: 1,
  630. page_size: 999,
  631. cate_id: -1,
  632. name: ''
  633. }
  634. return this.$axiosUser('get', '/api/pro/post/cate_post_list', data)
  635. },
  636. // 自定义表头
  637. renderHeader(h, item, type) {
  638. let label = ""
  639. const labels = {
  640. 'targetConfirms': '确认目标',
  641. 'resultInput': '录入结果',
  642. 'scoreSelf': '自评',
  643. 'scoreEachOther': '互评',
  644. 'scores': '评分',
  645. 'reviews': '审批',
  646. 'cc': '抄送'
  647. }
  648. label = labels[type];
  649. let that = this;
  650. return h('div', {
  651. class: type + '-class',
  652. style: { display: "flex", alignItems: "center", justifyContent: "center" }
  653. }, [
  654. h('el-button', {
  655. props: {
  656. size: 'small'
  657. },
  658. on: {
  659. click: function () {
  660. that.clickButton(type);
  661. }
  662. }
  663. }, label),
  664. ])
  665. },
  666. clickButton(nodeType) {
  667. this.handleNode = this.flowInfo.nodes.find(node => node.type === nodeType)
  668. let options = {
  669. 'targetConfirms': ['确认目标', '确认人'],
  670. 'resultInput': ['录入结果', '录入人'],
  671. 'scoreSelf': ['自评', ''],
  672. 'scoreEachOther': ['互评', '互评人'],
  673. 'scores': ['评分', '评分人'],
  674. 'reviews': ['审批', '审批人'],
  675. 'cc': ['抄送', '抄送人']
  676. }
  677. this.dialogTitle = options[nodeType][0]
  678. this.formLabel = options[nodeType][1]
  679. this.nodeType = nodeType; // 节点类型
  680. this.batchHandleDialog = true;
  681. },
  682. // 打开编辑规则内容弹框
  683. editContent(index, content, indicatorId) {
  684. this.selectIndex = index;
  685. this.content = content;
  686. this.selectIndicatorId = indicatorId;
  687. this.showEditContent = true
  688. },
  689. finishEditContent(content) {
  690. this.tableData[this.selectIndex].content = content
  691. },
  692. // 获取模板详情
  693. get_template_detail() {
  694. this.$axiosUser("get", `/performance/template/info/${this.user_info.site_id}/` + this.templateId).then(res => {
  695. let { data: { data: { title, flow } } } = res
  696. this.templateTitle = title || '模板名称'
  697. this.title = title || '模板名称'
  698. this.flowInfo = flow || {}
  699. })
  700. },
  701. // 获取表格数据
  702. get_table_data() {
  703. this.loading = true
  704. this.$axiosUser("get", `/performance/indicator/list/${this.user_info.site_id}/` + this.templateId).then(res => {
  705. this.tableData = res.data.data.list
  706. this.loading = false
  707. })
  708. },
  709. editTableData() { },
  710. // 编辑模板标题
  711. editTitle() {
  712. let title = this.title
  713. if (title !== null && title !== '') {
  714. let url = `/performance/template/title/${this.user_info.site_id}`
  715. this.$http.post(url, { templateId: this.templateId, title }).then(res => {
  716. if (res.code == 1) {
  717. this.$message.success("修改成功")
  718. this.editTitleDialogVisible = false
  719. this.get_template_detail();
  720. }
  721. })
  722. }
  723. },
  724. // 编辑指标名称,规则,权重,目标,单位
  725. handleEdit(props, value, id) {
  726. let url = '', data = {};
  727. url = `/performance/indicator/${props}/${this.user_info.site_id}/${this.templateId}`;
  728. data[props] = value;
  729. data['indicatorId'] = id;
  730. this.$http.post(url, data).then(res => {
  731. if (res.code == 0) return this.$message.error(res.msg || '操作失败')
  732. })
  733. },
  734. handleBtnClick(index, node, row) {
  735. this.handleStatusChange(index, row, node.type)
  736. },
  737. // 自评节点单独操作
  738. handleScoreSelf(row, index) {
  739. let { indicatorId, flow: { nodes } } = row
  740. let data = {
  741. indicatorId, // 指标ID
  742. nodes
  743. }
  744. let url = `/performance/indicator/flow/${this.user_info.site_id}/${this.templateId}`
  745. this.$http.post(url, data).then(res => {
  746. let { code, data } = res
  747. if (code == 1) {
  748. this.tableData.splice(index, 1, data); //替换元素
  749. this.$message.success("操作成功");
  750. } else {
  751. this.$message.error(res.message || '操作失败');
  752. }
  753. })
  754. },
  755. // 操作节点
  756. handleStatusChange(index, row, nodeType) {
  757. if (index !== -1) this.tagIndex = index // 子节点索引
  758. this.currentIndicator = row;
  759. let { indicatorId } = row;
  760. this.selectIndicatorId = indicatorId; // 指标ID
  761. this.selectNodes = row.flow.nodes; // 所有节点
  762. this.nodeType = nodeType; // 节点类型
  763. if (nodeType == 'targetConfirms') {
  764. this.dialogTitle = "确认目标"
  765. this.formLabel = "确认人"
  766. this.targetConfirms = true;
  767. }
  768. if (nodeType == 'resultInput') {
  769. this.dialogTitle = "录入结果"
  770. this.formLabel = "录入人"
  771. this.resultInput = true;
  772. }
  773. if (nodeType == 'scoreSelf') {
  774. this.dialogTitle = "自评"
  775. this.scoreSelf = true
  776. }
  777. if (nodeType == 'scoreEachOther') {
  778. this.dialogTitle = "互评"
  779. this.formLabel = "互评人"
  780. this.scoreEachOther = true
  781. }
  782. if (nodeType == 'scores') {
  783. this.dialogTitle = "评分"
  784. this.formLabel = "评分人"
  785. this.scores = true
  786. }
  787. if (nodeType == 'reviews') {
  788. this.dialogTitle = "审批"
  789. this.formLabel = "审批人"
  790. this.reviews = true
  791. }
  792. if (nodeType == 'cc') {
  793. this.dialogTitle = "抄送"
  794. this.formLabel = "抄送人"
  795. this.cc = true
  796. }
  797. },
  798. // 添加指标
  799. addData() {
  800. let url = `/performance/indicator/create/${this.user_info.site_id}/${this.templateId}`
  801. this.$http.post(url, {}).then(res => {
  802. let { data, code } = res
  803. if (code) {
  804. data.flow.nodes.forEach((item) => {
  805. if (item.type !== 'scores')
  806. item.enable = false
  807. })
  808. this.tableData.push(data)
  809. }
  810. })
  811. },
  812. handleSelectChange(val) {
  813. this.multipleSelection = val;
  814. },
  815. // 取消删除
  816. cancelDelete() {
  817. console.log("取消删除");
  818. },
  819. // 确认删除
  820. confirmDelete() {
  821. if (this.multipleSelection && this.multipleSelection.length > 0) {
  822. this.$confirm('确定删除选中的指标吗?', '提示', {
  823. type: 'warning'
  824. }).then(() => {
  825. // 创建一个包含异步任务的数组,每个任务都是一个 axios 请求
  826. const arrays = []
  827. this.multipleSelection.forEach(item => {
  828. arrays.push(this.deleteIndicator(item))
  829. })
  830. // 当所有请求都成功完成时,responses 是一个包含所有响应的数组
  831. Promise.all(arrays).then(responses => {
  832. // console.log(responses)
  833. this.get_table_data();
  834. }).catch(error => {
  835. // 如果任何一个请求失败,将会进入这个 catch 块
  836. console.log(error)
  837. })
  838. }).catch(() => { });
  839. }
  840. },
  841. // 删除指标
  842. deleteIndicator(item) {
  843. let url = `/performance/indicator/remove/${this.user_info.site_id}/${this.templateId}/${item.indicatorId}`
  844. return this.$axiosUser('post', url).then(res => {
  845. return res.data
  846. })
  847. },
  848. // 打开计算公式弹框
  849. openFormula(row, index) {
  850. this.currentIndicator = null;
  851. this.selectIndex = -1;
  852. this.currentIndicator = row;
  853. this.selectIndex = index;
  854. this.showFormula = true;
  855. },
  856. // 关闭编辑计算公式弹框
  857. closeDialog() {
  858. },
  859. // 全选复选框事件监听
  860. checkAllChangeFn(val) {
  861. this.loading = true
  862. if (val) {
  863. // 全选
  864. this.tableColumn.forEach(item => {
  865. item.isShow = true
  866. })
  867. } else {
  868. // 反全选
  869. this.tableColumn.forEach(item => {
  870. if (this.flowColumn.includes(item.label)) {
  871. item.isShow = false;
  872. } else {
  873. item.isShow = true
  874. }
  875. })
  876. }
  877. this.loading = false
  878. this.showPopover();
  879. },
  880. // 重置,flag: Boolean,全部重置为flag
  881. reset(flag) {
  882. this.tableColumn.forEach(item => {
  883. if (this.flowColumn.includes(item.label)) {
  884. item.isShow = false;
  885. } else {
  886. item.isShow = true
  887. }
  888. })
  889. this.showPopover();
  890. this.refreshTable();
  891. },
  892. // 表格列是否显示的方法
  893. showColumn(currentColumn) {
  894. return this.tableColumn.find(item => item.prop == currentColumn).isShow;
  895. },
  896. /* 选择列 */
  897. changeColumns(val) {
  898. this.tableColumn.forEach(item => {
  899. item.isShow = false;
  900. })
  901. // columns将val数组存在的值设为true,不存在的设为false
  902. val && val.forEach(item => {
  903. let current = this.tableColumn.find(i => i.label == item)
  904. current.isShow = true;
  905. })
  906. // 判断是否全选
  907. this.judgeIsCheckAll();
  908. // this.refreshTable();
  909. },
  910. // 重新渲染表格
  911. refreshTable() {
  912. this.$nextTick(() => {
  913. if (this.$refs.fmeaTableRef) this.$refs.fmeaTableRef.doLayout();
  914. })
  915. },
  916. // 气泡框出现
  917. showPopover() {
  918. this.checkColumns = []
  919. this.tableColumn.forEach(item => {
  920. if (item.isShow) {
  921. this.checkColumns.push(item.label)
  922. }
  923. })
  924. // 判断是否全选
  925. this.judgeIsCheckAll();
  926. },
  927. // 判断是否全选
  928. judgeIsCheckAll() {
  929. // 选中的长度 = 表格列的长度 全选按钮就选中
  930. if (this.checkColumns.length == this.tableColumn.length)
  931. this.checkAll = true
  932. else
  933. this.checkAll = false
  934. },
  935. finishHandle(nodes) {
  936. let data = nodes
  937. let url = `/performance/indicator/flow/${this.user_info.site_id}/${this.templateId}`
  938. this.$http.post(url, data).then(res => {
  939. let { code, data } = res
  940. if (code == 1) {
  941. let index = this.tableData.findIndex(table => table.indicatorId === data.indicatorId)
  942. this.tableData.splice(index, 1, data); //替换元素
  943. this.$message.success("操作成功");
  944. this.nodeType = ''
  945. this.dialogTitle = ''
  946. this.selectNodes = []
  947. this.currentIndicator = []
  948. this.selectIndicatorId = ''
  949. this.tagIndex = -1
  950. } else {
  951. this.$message.error(res.message || '操作失败');
  952. }
  953. })
  954. },
  955. closeNodeDialog() {
  956. console.log("关闭弹窗")
  957. this.tagIndex = -1 // 子节点索引
  958. this.currentIndicator = null;
  959. this.selectIndicatorId = null; // 指标ID
  960. this.selectNodes = []; // 所有节点
  961. this.nodeType = ''; // 节点类型
  962. },
  963. // 批量操作成功
  964. finishBatchHandle(data) {
  965. this.flowInfo = data;
  966. this.get_table_data();
  967. },
  968. // 编辑计算公式确定的回调
  969. onFormulaConfirm(formulas) {
  970. let url = `/performance/indicator/expression/${this.user_info.site_id}/${this.templateId}`;
  971. let { indicatorId } = this.currentIndicator;
  972. let params = {
  973. indicatorId,
  974. expression: {
  975. formulas: formulas.map(item => {
  976. return {
  977. condition: item.condition,
  978. expression: item.expression
  979. }
  980. })
  981. }
  982. }
  983. this.$http.post(url, params).then(res => {
  984. let { data, code } = res
  985. if (code) {
  986. this.tableData.splice(this.selectIndex, 1, data); //替换元素
  987. }
  988. })
  989. },
  990. // 发布考核
  991. publish() {
  992. this.showPublish = true;
  993. },
  994. // 发布考核弹框的回调
  995. onPubishConfirm(params, selectOkrs) {
  996. let templateId = this.templateId;
  997. let { title, startDate, endDate, cycleType, employeeIds, okrs, cateId } = params
  998. let employees = employeeIds.map(employee => ({
  999. employeeId: employee,
  1000. ids: [],
  1001. interviewFlow: {
  1002. nodes: [
  1003. {
  1004. id: "IT_1894283564934688769",
  1005. type: "interview",
  1006. allows: [],
  1007. enable: false,
  1008. weight: 0,
  1009. children: [],
  1010. assigneeIds: [],
  1011. leaderLevel: 1,
  1012. assigneeType: "self",
  1013. multipleType: "or"
  1014. }
  1015. ]
  1016. }
  1017. }))
  1018. let requireParams = {
  1019. title,
  1020. cycleType,
  1021. startDate,
  1022. endDate,
  1023. okrs,
  1024. templates: [
  1025. {
  1026. templateId,
  1027. employees
  1028. }
  1029. ],
  1030. cateId
  1031. }
  1032. // let url = `/performance/review/publish/${this.user_info.site_id}`;
  1033. // console.log(requireParams)
  1034. let url = `/performance/review/publish/templates/${this.user_info.site_id}`;
  1035. this.loading = true
  1036. this.$http.post(url, requireParams).then(res => {
  1037. console.log(res)
  1038. let { data, code } = res
  1039. this.loading = false
  1040. if (code == 1) {
  1041. this.$message.success("发布成功");
  1042. setTimeout(() => {
  1043. this.$router.go(-1)
  1044. }, 1000);
  1045. }
  1046. })
  1047. }
  1048. }
  1049. };
  1050. </script>
  1051. <style lang="scss">
  1052. .box {
  1053. .el-switch__core {
  1054. width: 30px !important;
  1055. height: 16px;
  1056. }
  1057. .el-switch__core::after {
  1058. width: 14px;
  1059. height: 14px;
  1060. margin-top: -1px;
  1061. }
  1062. .el-switch.is-checked .el-switch__core::after {
  1063. margin-left: -15px;
  1064. }
  1065. }
  1066. .introjs-helperLayer {
  1067. box-shadow: rgba(33, 33, 33, 0.8) 0px 0px 1px 0px, rgba(33, 33, 33, 0.5) 0px 0px 0px 5000px !important;
  1068. border: 3px dashed #409eff;
  1069. }
  1070. /* 调整 intro.js 弹出框的大小 */
  1071. .introjs-tooltip {
  1072. width: auto;
  1073. /* 自动调整宽度 */
  1074. max-width: 1600px;
  1075. /* 最大宽度 */
  1076. height: auto;
  1077. /* 自动调整高度 */
  1078. overflow: hidden;
  1079. /* 防止内容溢出 */
  1080. }
  1081. .new-tips {
  1082. color: #409eff;
  1083. line-height: 80px;
  1084. cursor: pointer;
  1085. }
  1086. .introjs-tooltip-title {
  1087. font-size: 16px;
  1088. width: 80%;
  1089. padding-top: 10px;
  1090. }
  1091. .warper {
  1092. width: 200px;
  1093. height: 100px;
  1094. line-height: 100px;
  1095. text-align: center;
  1096. border: 1px solid saddlebrown;
  1097. }
  1098. /* 重置引导组件样式(类似element-ui个人使用) */
  1099. .intro-tooltip {
  1100. color: #ffff;
  1101. background: #2c3e50;
  1102. }
  1103. /* 引导提示框的位置 */
  1104. .introjs-bottom-left-aligned {
  1105. left: 45% !important;
  1106. }
  1107. .introjs-right,
  1108. .introjs-left {
  1109. top: 30%;
  1110. }
  1111. .intro-highlight {
  1112. background: rgba(255, 255, 255, 0.5);
  1113. }
  1114. .introjs-arrow.left {
  1115. border-right-color: #2c3e50;
  1116. }
  1117. .introjs-arrow.top {
  1118. border-bottom-color: #2c3e50;
  1119. }
  1120. .introjs-arrow.right {
  1121. border-left-color: #2c3e50;
  1122. }
  1123. .introjs-arrow.bottom {
  1124. border-top-color: #2c3e50;
  1125. }
  1126. /* 提示框头部区域 */
  1127. .introjs-tooltip-header {
  1128. padding-right: 0 !important;
  1129. padding-top: 0 !important;
  1130. }
  1131. .introjs-skipbutton {
  1132. color: #409eff !important;
  1133. font-size: 14px !important;
  1134. font-weight: normal !important;
  1135. // padding: 8px 10px !important ;
  1136. }
  1137. .introjs-tooltipbuttons {
  1138. border: none !important;
  1139. }
  1140. .introjs-tooltiptext {
  1141. font-size: 14px !important;
  1142. padding: 15px !important;
  1143. }
  1144. /* 提示框按钮 */
  1145. .introjs-tooltipbuttons {
  1146. display: flex;
  1147. align-items: center;
  1148. justify-content: center;
  1149. }
  1150. .introjs-button {
  1151. width: 50px !important;
  1152. text-align: center;
  1153. padding: 4px !important;
  1154. font-size: 12px !important;
  1155. font-weight: 500 !important;
  1156. border-radius: 3px !important;
  1157. border: none !important;
  1158. }
  1159. .introjs-button:last-child {
  1160. margin-left: 10px;
  1161. }
  1162. .introjs-prevbutton {
  1163. color: #606266 !important;
  1164. background: #fff !important;
  1165. border: 1px solid #dcdfe6 !important;
  1166. }
  1167. .introjs-nextbutton {
  1168. color: #fff !important;
  1169. background-color: #409eff !important;
  1170. border-color: #409eff !important;
  1171. }
  1172. .introjs-disabled {
  1173. color: #9e9e9e !important;
  1174. border-color: #bdbdbd !important;
  1175. background-color: #f4f4f4 !important;
  1176. }
  1177. </style>
  1178. <style scoped="scoped" lang="scss">
  1179. .oneLine {
  1180. overflow: hidden;
  1181. white-space: nowrap;
  1182. text-overflow: ellipsis;
  1183. }
  1184. .box {
  1185. width: 100%;
  1186. height: 100%;
  1187. display: flex;
  1188. flex-direction: column;
  1189. padding: 0 20px;
  1190. font-size: 14px;
  1191. background-color: #fff;
  1192. box-sizing: border-box;
  1193. border-radius: 4px;
  1194. /* 设置滚动条的宽度和背景色 */
  1195. ::v-deep .el-table__body-wrapper::-webkit-scrollbar {
  1196. width: 10px;
  1197. height: 10px;
  1198. background-color: #f9f9f9;
  1199. }
  1200. /* 设置滚动条滑块的样式 */
  1201. ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb {
  1202. border-radius: 6px;
  1203. background-color: #c1c1c1;
  1204. }
  1205. /* 设置滚动条滑块hover样式 */
  1206. ::v-deep .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
  1207. background-color: #a8a8a8;
  1208. }
  1209. /* 设置滚动条轨道的样式 */
  1210. ::v-deep .el-table__body-wrapper::-webkit-scrollbar-track {
  1211. box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
  1212. border-radius: 6px;
  1213. background: #ededed;
  1214. }
  1215. /*头部样式*/
  1216. .header-content {
  1217. position: relative;
  1218. box-sizing: border-box;
  1219. height: 60px;
  1220. justify-content: space-between;
  1221. .header-left {
  1222. width: 230px;
  1223. box-sizing: border-box;
  1224. height: 60px;
  1225. cursor: pointer;
  1226. .el-icon-arrow-left {
  1227. font-size: 22px;
  1228. }
  1229. &:hover {
  1230. .el-icon-arrow-left {
  1231. background-color: #f5f7fa;
  1232. color: #222;
  1233. }
  1234. }
  1235. .text {
  1236. font-size: 16px;
  1237. font-weight: 600;
  1238. padding-left: 50px;
  1239. &::before {
  1240. position: absolute;
  1241. content: '';
  1242. width: 1px;
  1243. height: 36px;
  1244. background-color: #ebebeb;
  1245. left: 44px;
  1246. top: 50%;
  1247. margin-top: -18px;
  1248. }
  1249. }
  1250. }
  1251. .header-right {
  1252. text-align: right;
  1253. .icon {
  1254. width: 40px;
  1255. height: 40px;
  1256. border: 1px solid #ccc;
  1257. border-radius: 50%;
  1258. font-size: 20px;
  1259. color: #999;
  1260. display: flex;
  1261. align-items: center;
  1262. justify-content: center;
  1263. transition: all 0.3s;
  1264. &:hover {
  1265. cursor: pointer;
  1266. background: #f5f5f5;
  1267. }
  1268. }
  1269. }
  1270. }
  1271. .plus-button {
  1272. display: block;
  1273. margin: 10px auto;
  1274. }
  1275. .table-box {
  1276. flex: 1;
  1277. width: 100%;
  1278. overflow-y: auto;
  1279. /* 设置滚动条的宽度和背景色 */
  1280. &::-webkit-scrollbar {
  1281. width: 6px;
  1282. height: 6px;
  1283. background-color: #f9f9f9;
  1284. }
  1285. /* 设置滚动条滑块的样式 */
  1286. &::-webkit-scrollbar-thumb {
  1287. border-radius: 6px;
  1288. background-color: #c1c1c1;
  1289. }
  1290. /* 设置滚动条滑块hover样式 */
  1291. &::-webkit-scrollbar-thumb:hover {
  1292. background-color: #a8a8a8;
  1293. }
  1294. /* 设置滚动条轨道的样式 */
  1295. &::-webkit-scrollbar-track {
  1296. box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
  1297. border-radius: 6px;
  1298. background: #ededed;
  1299. }
  1300. }
  1301. }
  1302. </style>