From ff28e6db2f3535812a753a7213cc106ece8f297c Mon Sep 17 00:00:00 2001 From: chenrui <1187576398@qq.com> Date: 星期五, 28 二月 2025 14:58:14 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- src/views/CNAS/personnel/personnelInfo/index.vue | 40 +- src/api/cnas/personal/personalTraining.js | 2 src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue | 65 +++- src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue | 2 src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue | 245 +++++++--------- src/views/CNAS/personnel/personnelInfo/components/Edit.vue | 1 src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue | 27 + src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue | 194 ++++++------- src/components/Pagination/index.vue | 3 src/api/cnas/personal/personRewardPunishmentRecord.js | 35 ++ src/assets/styles/ruoyi.scss | 2 src/api/cnas/personal/personTrainingRecord.js | 27 + src/main.js | 4 src/api/cnas/personal/personJobResponsibilities.js | 35 ++ src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue | 108 +++--- package.json | 1 16 files changed, 439 insertions(+), 352 deletions(-) diff --git a/package.json b/package.json index 2b89237..4379600 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "jsencrypt": "3.0.0-rc.1", "jspdf": "^3.0.0", "mammoth": "^1.9.0", + "moment": "^2.30.1", "nprogress": "0.2.0", "pako": "^2.1.0", "print-js": "^1.6.0", diff --git a/src/api/cnas/personal/personJobResponsibilities.js b/src/api/cnas/personal/personJobResponsibilities.js new file mode 100644 index 0000000..0c2673b --- /dev/null +++ b/src/api/cnas/personal/personJobResponsibilities.js @@ -0,0 +1,35 @@ +import request from "@/utils/request"; + +// 鍒嗛〉鏌ヨ宀椾綅鑱岃矗 +export function personJobResponsibilitiesSelect(query) { + return request({ + url: "/personJobResponsibilities/personJobResponsibilitiesSelect", + method: "get", + params: query + }); +} +// 鏂板宀椾綅鑱岃矗 +export function personJobResponsibilitiesSave(query) { + return request({ + url: "/personJobResponsibilities/personJobResponsibilitiesSave", + method: "post", + data: query + }); +} +// 瀵煎嚭宀椾綅鑱岃矗 +export function exportPersonJobResponsibilities(query) { + return request({ + url: "/personJobResponsibilities/exportPersonJobResponsibilities", + method: "post", + params: query, + responseType: "blob" + }); +} +// 鍒犻櫎宀椾綅鑱岃矗 +export function personJobResponsibilitiesDelete(query) { + return request({ + url: "/personJobResponsibilities/personJobResponsibilitiesDelete", + method: "delete ", + params: query + }); +} diff --git a/src/api/cnas/personal/personRewardPunishmentRecord.js b/src/api/cnas/personal/personRewardPunishmentRecord.js new file mode 100644 index 0000000..c160073 --- /dev/null +++ b/src/api/cnas/personal/personRewardPunishmentRecord.js @@ -0,0 +1,35 @@ +import request from "@/utils/request"; + +// 浜哄憳 - 濂栨儵璁板綍 鍒嗛〉鏌ヨ +export function rewardPunishmentPage(query) { + return request({ + url: "/personRewardPunishmentRecord/rewardPunishmentPage", + method: "get", + params: query + }); +} +// 浜哄憳 - 濂栨儵璁板綍 瀵煎嚭 +export function rewardPunishmentExport(query) { + return request({ + url: "/personRewardPunishmentRecord/rewardPunishmentExport", + method: "get", + params: query, + responseType: 'blob' + }); +} +// 浜哄憳 - 濂栨儵璁板綍 鏂板/鏇存柊 +export function addOrUpdateRewardPunishment(query) { + return request({ + url: "/personRewardPunishmentRecord/addOrUpdateRewardPunishment", + method: "post", + data: query, + }); +} +// 浜哄憳 - 濂栨儵璁板綍 鏂板/鏇存柊 +export function deleteRewardPunishment(query) { + return request({ + url: "/personRewardPunishmentRecord/deleteRewardPunishment", + method: "delete", + params: query, + }); +} diff --git a/src/api/cnas/personal/personTrainingRecord.js b/src/api/cnas/personal/personTrainingRecord.js new file mode 100644 index 0000000..6b75b4d --- /dev/null +++ b/src/api/cnas/personal/personTrainingRecord.js @@ -0,0 +1,27 @@ +import request from "@/utils/request"; + +// 瀵煎嚭鍩硅璁板綍 +export function exportTrainingRecord(query) { + return request({ + url: "/personTrainingRecord/exportTrainingRecord", + method: "get", + params: query, + responseType: 'blob' + }); +} +// 鏌ヨ浜哄憳 鍩硅璁板綍 +export function trainingSelectTrainingRecord(query) { + return request({ + url: "/personTrainingRecord/trainingSelectTrainingRecord", + method: "get", + params: query, + }); +} +// 鏌ヨ浜哄憳鏄庣粏 鍩硅璁板綍 +export function queryPersonnelDetails(query) { + return request({ + url: "/personTrainingRecord/queryPersonnelDetails", + method: "get", + params: query, + }); +} diff --git a/src/api/cnas/personal/personalTraining.js b/src/api/cnas/personal/personalTraining.js index d814ce4..cdca93c 100644 --- a/src/api/cnas/personal/personalTraining.js +++ b/src/api/cnas/personal/personalTraining.js @@ -3,7 +3,7 @@ // 鏌ヨ浜哄憳鍩硅 export function personTraining(query) { return request({ - url: "/personTraining/personTraining", + url: "/personTraining/personTrainingSelect", method: "get", params: query }); diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss index 7e44513..8dfe1d0 100644 --- a/src/assets/styles/ruoyi.scss +++ b/src/assets/styles/ruoyi.scss @@ -121,7 +121,7 @@ height: 32px; margin-bottom: 10px; margin-top: 15px; - padding: 10px 20px !important; + padding: 0 20px !important; } /* tree border */ diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue index 56f5a6b..9be5ddb 100644 --- a/src/components/Pagination/index.vue +++ b/src/components/Pagination/index.vue @@ -106,7 +106,8 @@ <style scoped> .pagination-container { background: #fff; - padding: 32px 16px; + padding: 28px 16px; + margin-top: 10px; } .pagination-container.hidden { display: none; diff --git a/src/main.js b/src/main.js index 5809760..beaf8ef 100644 --- a/src/main.js +++ b/src/main.js @@ -49,6 +49,8 @@ import DictData from "@/components/DictData"; import { checkPermi } from "@/utils/permission"; // 鏉冮檺鍒ゆ柇鍑芥暟 import { getToken } from "@/utils/auth"; +// 鏃堕棿杞崲 +import Moment from 'moment' // 鍏ㄥ眬鏂规硶鎸傝浇 Vue.prototype.getDicts = getDicts; @@ -80,6 +82,8 @@ }); } }) +Vue.use(Moment) +Vue.prototype.$moment = Moment // 鍏ㄥ眬缁勪欢鎸傝浇 Vue.component("DictTag", DictTag); diff --git a/src/views/CNAS/personnel/personnelInfo/components/Edit.vue b/src/views/CNAS/personnel/personnelInfo/components/Edit.vue index 6dff2e6..3992697 100644 --- a/src/views/CNAS/personnel/personnelInfo/components/Edit.vue +++ b/src/views/CNAS/personnel/personnelInfo/components/Edit.vue @@ -222,7 +222,6 @@ }, addUserTableInfo: { name: null, - departLimsId: '1', }, multipleSelection: [], userList: [], diff --git a/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue b/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue index 36364cf..e9938c7 100644 --- a/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue +++ b/src/views/CNAS/personnel/personnelInfo/components/ViewRecord.vue @@ -35,6 +35,7 @@ import filePreview from '@/components/Preview/filePreview.vue'; import limsTable from "@/components/Table/lims-table.vue"; import {delTrainingDetailedFileList, getTrainingDetailedFileList} from "@/api/cnas/personal/personalTraining"; +import {delCustomById} from "@/api/system/customer"; export default { name: 'ViewRecord', @@ -126,15 +127,21 @@ }, // 鍒犻櫎 delete (row) { - this.tableLoading = true - delTrainingDetailedFileList({detailedFileId: row.detailedFileId}).then(res => { - this.tableLoading = false - this.$message.success('鍒犻櫎鎴愬姛') - this.searchTableList() - }).catch(err => { - this.tableLoading = false - console.log('err---', err); - }) + this.$confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(() => { + this.tableLoading = true + delTrainingDetailedFileList({detailedFileId: row.detailedFileId}).then(res => { + this.tableLoading = false + this.$message.success('鍒犻櫎鎴愬姛') + this.searchTableList() + }).catch(err => { + this.tableLoading = false + console.log('err---', err); + }) + }).catch(() => {}) }, // 涓婁紶楠岃瘉 fileBeforeUpload(file) { @@ -167,7 +174,7 @@ }, computed: { fileAction() { - return this.javaApi + '/personTraining/delTrainingDetailedFileList' + return this.javaApi + '/personTraining/uploadTrainingDetailedFile' } }, diff --git a/src/views/CNAS/personnel/personnelInfo/index.vue b/src/views/CNAS/personnel/personnelInfo/index.vue index a55381e..5cbb11a 100644 --- a/src/views/CNAS/personnel/personnelInfo/index.vue +++ b/src/views/CNAS/personnel/personnelInfo/index.vue @@ -57,24 +57,24 @@ @updatePerson="updatePerson"></PersonnelList> <personnelInformation v-if="activeName === '浜哄憳鍩烘湰淇℃伅' && !isShowAll" :clickNodeVal="clickNodeVal"></personnelInformation> </el-tab-pane> -<!-- <el-tab-pane label="鍩硅璁″垝" name="鍩硅璁″垝">--> -<!-- <PersonnelTraining v-if="activeName === '鍩硅璁″垝'" ref="personnelTraining"--> -<!-- :departId="departId" :isDepartment="isDepartment"></PersonnelTraining>--> -<!-- </el-tab-pane>--> -<!-- <el-tab-pane label="宀椾綅鑱岃矗" name="宀椾綅鑱岃矗">--> -<!-- <job-responsibilities v-if="activeName === '宀椾綅鑱岃矗'" ref="jobResponsibilities"--> -<!-- :departId="departId"--> -<!-- :isDepartment="isDepartment"></job-responsibilities>--> -<!-- </el-tab-pane>--> -<!-- <el-tab-pane label="濂栨儵璁板綍" name="濂栨儵璁板綍">--> -<!-- <rewardPunishmentRecord v-if="activeName === '濂栨儵璁板綍'"--> -<!-- :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord>--> -<!-- </el-tab-pane>--> -<!-- <el-tab-pane label="鍩硅璁板綍" name="鍩硅璁板綍">--> -<!-- <training-record v-if="activeName === '鍩硅璁板綍'" ref="trainingRecord"--> -<!-- :departId="departId"--> -<!-- :isDepartment="isDepartment"></training-record>--> -<!-- </el-tab-pane>--> + <el-tab-pane label="鍩硅璁″垝" name="鍩硅璁″垝"> + <PersonnelTraining v-if="activeName === '鍩硅璁″垝'" ref="personnelTraining" + :departId="departId" :isDepartment="isDepartment"></PersonnelTraining> + </el-tab-pane> + <el-tab-pane label="宀椾綅鑱岃矗" name="宀椾綅鑱岃矗"> + <job-responsibilities v-if="activeName === '宀椾綅鑱岃矗'" ref="jobResponsibilities" + :departId="departId" + :isDepartment="isDepartment"></job-responsibilities> + </el-tab-pane> + <el-tab-pane label="濂栨儵璁板綍" name="濂栨儵璁板綍"> + <rewardPunishmentRecord v-if="activeName === '濂栨儵璁板綍'" + :departId="departId" :isDepartment="isDepartment"></rewardPunishmentRecord> + </el-tab-pane> + <el-tab-pane label="鍩硅璁板綍" name="鍩硅璁板綍"> + <training-record v-if="activeName === '鍩硅璁板綍'" ref="trainingRecord" + :departId="departId" + :isDepartment="isDepartment"></training-record> + </el-tab-pane> <!-- <el-tab-pane label="浠昏亴鎺堟潈璁板綍" name="浠昏亴鎺堟潈璁板綍">--> <!-- <Mandate v-if="activeName === '浠昏亴鎺堟潈璁板綍'" ref="manDateRef" :departId="departId" :isDepartment="isDepartment"></Mandate>--> <!-- </el-tab-pane>--> @@ -274,6 +274,10 @@ height: 14px; /* 璁剧疆婊氬姩鏉″搴� */ } +.node_i { + color: orange; + font-size: 18px; +} .custom-tree-node { width: 80%; line-height: 32px; diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue b/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue index 2f7d422..1ae74e8 100644 --- a/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue +++ b/src/views/CNAS/personnel/personnelInfo/tabs/job-responsibilities.vue @@ -1,17 +1,22 @@ <!-- 宀椾綅鑱岃矗 --> <template> <div class="view"> - <div style="text-align: left; margin-bottom: 15px;padding: 0 10px"> - <label>鍛樺伐锛�</label> - <el-input v-model="userName" clearable placeholder="璇疯緭鍏ュ憳宸�" size="small" style="width: 20vh;"></el-input> - <el-button size="small" type="primary" @click="refreshTable">鏌ヨ</el-button> - <div v-if="isDepartment" style="float: right;"> + <div style="display: flex;justify-content: space-between;"> + <el-form ref="page" size="small" :inline="true"> + <el-form-item label="鍛樺伐"> + <el-input v-model="userName" clearable placeholder="璇疯緭鍏ュ憳宸�" size="small" style="width: 20vh;"></el-input> + </el-form-item> + <el-form-item> + <el-button size="small" type="primary" @click="refreshTable">鏌ヨ</el-button> + </el-form-item> + </el-form> + <div> <el-button size="small" type="primary" @click="addPost">鏂板</el-button> <!-- <el-button size="small" type="primary">瀵煎嚭excel</el-button>--> </div> </div> - <div class="table" style="padding: 0 10px"> - <el-table :data="tableData" height="70vh" style="width: 100%"> + <div class="table"> + <el-table :data="tableData" v-loading="tableLoading" height="66.5vh" style="width: 100%"> <el-table-column label="搴忓彿" type="index" width="60"></el-table-column> <el-table-column label="鍛樺伐缂栧彿" min-width="120" prop="account"></el-table-column> <el-table-column label="宀椾綅鍚嶇О" min-width="180" prop="postName"></el-table-column> @@ -22,7 +27,7 @@ <el-table-column label="浠昏亴浜哄鏍告棩鏈�" min-width="180" prop="incumbentDate"></el-table-column> <el-table-column label="涓荤" min-width="180" prop="supervisorName"></el-table-column> <el-table-column label="涓荤瀹℃牳鏃ユ湡" min-width="180" prop="supervisorDate"></el-table-column> - <el-table-column fixed="right" label="鎿嶄綔" width="140"> + <el-table-column fixed="right" label="鎿嶄綔" width="140" align="center"> <template v-slot="scope"> <el-button v-if="!isDepartment || scope.row.currentState === '鍏抽棴'" size="small" type="text" @click="handleViewClick(scope.row, 'view')">鏌ョ湅 @@ -31,12 +36,14 @@ @click="handleViewClick(scope.row, 'edit')">缂栬緫 </el-button> <el-button size="small" type="text" @click="downLoadPost(scope.row)">瀵煎嚭</el-button> - <el-button v-if="isDepartment" size="small" type="text" @click="deletePost(scope.row)">鍒犻櫎</el-button> + <el-button v-if="isDepartment" size="small" style="color: #f56c6c" type="text" @click="deletePost(scope.row)">鍒犻櫎</el-button> </template> </el-table-column> </el-table> <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]" :total="search.total" layout="->,total, sizes, prev, pager, next, jumper" + background + style="margin-top: 10px" @size-change="handleSizeChange" @current-change="handleCurrentChange"> </el-pagination> @@ -123,13 +130,21 @@ </template> <script> -// import { dateFormat } from '../../../util/date'; +import { dateFormat } from '@/utils/date' +import { + exportPersonJobResponsibilities, personJobResponsibilitiesDelete, + personJobResponsibilitiesSave, + personJobResponsibilitiesSelect +} from "@/api/cnas/personal/personJobResponsibilities"; +import {selectUserCondition} from "@/api/cnas/resourceDemand/facilitiesEnvironment/facilitiesAndEnvironment"; +import {mapGetters} from "vuex"; export default { data() { return { userName: '', tableData: [], + tableLoading: false, responsibleOptions: [], search: { size: 20, @@ -192,19 +207,32 @@ // 鏌ヨ鍒楄〃淇℃伅 getPostList(userId) { this.search.userId = userId; - const name = this.isDepartment ? 'departmentId' : 'userId'; - this.$axios.get(this.$api.personnel.personJobResponsibilitiesSelect + '?userName=' + this.userName + `&${name}=` + this.search.userId + '&size=' + this.search.size + '¤t=' + this.search.current).then(res => { - if (res.code === 201) return; + const params = this.isDepartment ? { + userName: this.userName, + departmentId: this.search.userId, + size: this.search.size, + current: this.search.current, + }: { + userName: this.userName, + userId: this.search.userId, + size: this.search.size, + current: this.search.current, + } + this.tableLoading = true + personJobResponsibilitiesSelect(params).then(res => { + this.tableLoading = false this.tableData = res.data.records; this.search.total = res.data.total; - }); + }).catch(err => { + this.tableLoading = false + }) }, //鎻愪氦琛ㄥ崟 async submitForm(saveState) { this.$refs.form.validate((valid) => { if (valid === true || saveState !== '1submit') { // 缁欏綋鍓嶇幆鑺傝缃垱寤轰汉涓庢椂闂� - let user = JSON.parse(localStorage.getItem('user')); + let user = this.nickName; const dateTime = dateFormat(new Date()); // 鑾峰彇褰撳墠鐜妭鎿嶄綔浜轰笌鏃ユ湡 switch (this.currentStep) { @@ -254,12 +282,7 @@ } // 鑾峰彇褰撳墠鐘舵�� this.form.currentState = currentStepAction === 3 ? '鍏抽棴' : this.steps[currentStepAction]; - this.$axios.post(this.$api.personnel.personJobResponsibilitiesSave, this.form, { - headers: { - 'Content-Type': 'application/json' - }, - noQs: true - }).then(res => { + personJobResponsibilitiesSave(this.form).then(res => { if (res.code == 200) { this.$message.success('鎻愪氦鎴愬姛'); this.getPostList(this.departId); @@ -307,34 +330,10 @@ }, // 涓嬭浇宀椾綅鑱岃矗 downLoadPost(row) { - this.$axios.post(this.$api.personPostAuthorizationRecord.exportPersonJobResponsibilities,{id:row.id},{responseType: "blob"}).then(res => { + exportPersonJobResponsibilities({id:row.id}).then(res => { const blob = new Blob([res],{ type: 'application/octet-stream' }); - //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆 - let reader = new FileReader(); - reader.readAsText(blob, 'utf-8'); - reader.onload = () => { - try { - let result = JSON.parse(reader.result); - if (result.message) { - this.$message.error(result.message); - } else { - const url = URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = url; - link.download = row.incumbentName+'-宀椾綅鑱岃矗'+'.docx'; - link.click(); - this.$message.success('瀵煎嚭鎴愬姛') - } - } catch (err) { - console.log(err); - const url = URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = url; - link.download = row.incumbentName+'-宀椾綅鑱岃矗'+'.docx'; - link.click(); - this.$message.success('瀵煎嚭鎴愬姛') - } - } + this.$download.saveAs(blob, row.incumbentName+'-宀椾綅鑱岃矗'+'.docx'); + this.$message.success('瀵煎嚭鎴愬姛') }) }, // 鍒犻櫎宀椾綅鑱岃矗 @@ -344,7 +343,7 @@ cancelButtonText: '鍙栨秷', type: 'warning' }).then(() => { - this.$axios.delete(this.$api.personnel.personJobResponsibilitiesDelete + '?id=' + row.id).then(res => { + personJobResponsibilitiesDelete({id: row.id}).then(res => { if (res.code == 200) { this.$message.success('鍒犻櫎鎴愬姛'); this.getPostList(this.departId); @@ -362,11 +361,11 @@ }, // 鑾峰彇璐熻矗浜轰俊鎭帴鍙� getUserList() { - this.$axios.get(this.$api.deviceScope.selectUserList).then(res => { + selectUserCondition().then(res => { if (res.code == 200) { - this.responsibleOptions = res.data; + this.responsibleOptions = res.data } - }); + }) }, choiceStep(index) { this.currentStepClick = index; @@ -386,7 +385,10 @@ this.getPostList(newId); } } - } + }, + computed: { + ...mapGetters(['nickName']) + }, }; </script> <style scoped> diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue index edf7b44..92e0233 100644 --- a/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue +++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnel-list.vue @@ -48,7 +48,7 @@ :total="page.total" background layout="->,total, sizes, prev, pager, next, jumper" - style="margin-top: 16px" + style="margin-top: 10px" @size-change="handleSizeChange" @current-change="handleCurrentChange" > diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue index 8af11b0..46c637d 100644 --- a/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue +++ b/src/views/CNAS/personnel/personnelInfo/tabs/personnelTraining.vue @@ -2,6 +2,9 @@ <template> <div class="flex_column"> <div v-if="!editPlanShow && isDepartment"> + <div class="title"> + <span style="font-weight: bold">骞村害璁″垝</span> + </div> <div style="display: flex;justify-content: space-between;"> <el-form :model="page" ref="page" size="small" :inline="true"> <el-form-item label="缂栧埗浜�"> @@ -17,11 +20,14 @@ </div> <lims-table :tableData="yearPlanTableData" :column="yearPlanColumn" :currentChange="currentChange" - @pagination="pagination" :height="'calc(100vh - 290px)'" + @pagination="pagination" height="40vh" :page="page" :tableLoading="yearLoading"></lims-table> </div> <div v-if="!editPlanShow" class="table"> - <div v-if="!editPlanShow && isDepartment"> + <div> + <div class="title"> + <span style="font-weight: bold">骞村害璁″垝鏄庣粏</span> + </div> <div style="display: flex;justify-content: space-between;"> <el-form :model="inDetailForm" ref="inDetailForm" size="small" :inline="true"> <el-form-item label="鍩硅璁插笀"> @@ -42,10 +48,10 @@ </div> </div> <lims-table :tableData="inDetailPlanTableData" :column="inDetailPlanColumn" - :currentChange="currentChange" :height="isDepartment ? '45vh' : '68vh' " + :height="isDepartment ? '40vh' : '62vh' " :isSelection="true" :handleSelectionChange="handleSelectionChange" @pagination="pagination1" - :page="inDetailPagination" :tableLoading="yearLoading"></lims-table> + :page="inDetailPagination" :tableLoading="yearDetailLoading"></lims-table> </div> </div> <Add ref="addPlan" :currentChangeRow="currentChangeRow" @search="getInDetailPlan(currentRowId, departId)"></Add> @@ -167,6 +173,7 @@ trainingDate: '', }, yearLoading: false, + yearDetailLoading: false, yearPlanTableData: [], // 骞村害璁″垝琛ㄦ暟鎹� yearPlanColumn: [ { @@ -292,7 +299,7 @@ name: '鎵瑰噯', type: 'text', disabled: (row) => { - if(row.approvalStatus === 1 || this.userId != row.approverId) { + if(row.approvalStatus === 1 || this.userId != row.approverId || row.reviewerStatus != 1) { return true; } else { return false; @@ -477,6 +484,7 @@ }, // 鏌ヨ-骞村害璁″垝琛� getYearPlanList(userId) { + this.yearLoading = true const params = this.isDepartment ? { departmentId: userId, @@ -490,13 +498,16 @@ compilerName: this.page.compilerName, } personTraining(params).then(res => { + this.yearLoading = false this.yearPlanTableData = res.data.records; this.pagination.total = res.data.total; if (this.yearPlanTableData.length > 0) { this.currentRowId = this.yearPlanTableData[0].id this.currentChange(this.yearPlanTableData[0]) } - }); + }).catch(err => { + this.yearLoading = false + }) }, pagination (page) { this.page.size = page.limit @@ -530,10 +541,14 @@ trainingLecturerName: this.inDetailForm.trainingLecturerName, trainingDate: this.inDetailForm.trainingDate, } + this.yearDetailLoading = true queryTheAnnualPlanDetailsTable(params).then(res => { + this.yearDetailLoading = false this.inDetailPlanTableData = res.data.records; this.inDetailPagination.total = res.data.total; - }); + }).catch(err => { + this.yearDetailLoading = false + }) }, pagination1 (page) { this.inDetailPagination.size = page.limit @@ -639,7 +654,7 @@ this.uploadDia = false this.uploading = false if (response.code != 200) { - this.$message.error(response.message) + this.$message.error(response.msg) return } this.$message.success('涓婁紶鎴愬姛') @@ -761,23 +776,27 @@ overflow: auto; justify-content: space-between; } - -.pagination { - display: flex; - justify-content: space-between -} - -.items_center { - display: flex; - align-items: center; -} - -.date_box { - margin: 0 5px; -} - .search { width: 150px; margin: 0 16px; } +.title { + position: relative; + font-size: 16px; + color: #333; + font-weight: 400; + padding-left: 10px; + margin-bottom: 10px; +} + +.title::before { + position: absolute; + left: 0; + top: 4px; + content: ''; + width: 4px; + height: 16px; + background-color: #3A7BFA; + border-radius: 2px; +} </style> diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue b/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue index 344051f..40b2f82 100644 --- a/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue +++ b/src/views/CNAS/personnel/personnelInfo/tabs/reward-punishment-record.vue @@ -1,33 +1,41 @@ <!-- 濂栨儵璁板綍 --> <template> <div> - <div style="text-align: left; margin-bottom: 15px;"> - <label>濮撳悕</label> - <el-input v-model="search.userName" clearable placeholder="璇疯緭鍏ュ叧閿瓧" size="small" style="width: 20vh;"></el-input> - <label style="margin-left: 1em">濂栨儵鏃ユ湡</label> - <el-date-picker - v-model="search.searchTimeList" - :picker-options="pickerOptions" - align="right" - clearable - end-placeholder="缁撴潫鏃ユ湡" - format="yyyy-MM-dd" - range-separator="鑷�" - size="small" - start-placeholder="寮�濮嬫棩鏈�" - style="width: 20%" - type="daterange" - unlink-panels - value-format="yyyy-MM-dd 00:00:00"> - </el-date-picker> - <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button> - <div style="float: right;"> - <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">瀵煎嚭</el-button> - <el-button size="small" type="primary" @click="addRow">鏂板</el-button> + <div class="view"> + <div style="display: flex;justify-content: space-between;"> + <el-form :model="search" ref="page" size="small" :inline="true"> + <el-form-item label="濮撳悕"> + <el-input v-model="search.userName" clearable placeholder="璇疯緭鍏ュ叧閿瓧" size="small" style="width: 20vh;"></el-input> + </el-form-item> + <el-form-item label="濂栨儵鏃ユ湡"> + <el-date-picker + v-model="search.searchTimeList" + :picker-options="pickerOptions" + align="right" + clearable + end-placeholder="缁撴潫鏃ユ湡" + format="yyyy-MM-dd" + range-separator="鑷�" + size="small" + start-placeholder="寮�濮嬫棩鏈�" + style="width: 100%" + type="daterange" + unlink-panels + value-format="yyyy-MM-dd 00:00:00"> + </el-date-picker> + </el-form-item> + <el-form-item> + <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button> + </el-form-item> + </el-form> + <div> + <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">瀵煎嚭</el-button> + <el-button size="small" type="primary" @click="addRow">鏂板</el-button> + </div> </div> </div> <div class="table"> - <el-table :data="tableData" height="70vh" style="width: 100%"> + <el-table :data="tableData" v-loading="tableLoading" height="66.5vh" style="width: 100%"> <el-table-column label="搴忓彿" type="index" width="120"> <template v-slot="scope"> <span>{{ (search.current - 1) * search.size + scope.$index + 1 }}</span> @@ -49,22 +57,25 @@ </el-table-column> <el-table-column label="鍒涘缓浜�" min-width="180" prop="createUserName"> </el-table-column> - <el-table-column fixed="right" label="鎿嶄綔" width="100"> + <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center"> <template v-slot="scope"> <el-button size="small" type="text" @click="editForm(scope.row)">缂栬緫</el-button> - <el-button size="small" type="text" @click="deleteRow(scope.row)">鍒犻櫎</el-button> + <el-button size="small" type="text" style="color: #f56c6c" @click="deleteRow(scope.row)">鍒犻櫎</el-button> </template> </el-table-column> </el-table> - <el-pagination :current-page="1" :page-size="search.size" :page-sizes="[10, 20, 30, 50, 100]" + <el-pagination :current-page="1" :page-size="search.size" + :page-sizes="[10, 20, 30, 50, 100]" :total="search.total" layout="->,total, sizes, prev, pager, next, jumper" + background + style="margin-top: 10px" @size-change="handleSizeChange" @current-change="handleCurrentChange"> </el-pagination> </div> <el-dialog :visible.sync="dialogVisible" - title="鎻愮ず" + title="濂栨儵璁板綍" width="50%" @open="getUserList"> <div style="height: 40vh"> @@ -119,14 +130,22 @@ </el-form> </div> <span slot="footer" class="dialog-footer"> - <el-button @click="dialogVisible = false">鍙� 娑�</el-button> - <el-button type="primary" @click="saveOrUpdate">纭� 瀹�</el-button> - </span> + <el-button @click="dialogVisible = false">鍙� 娑�</el-button> + <el-button type="primary" @click="saveOrUpdate">纭� 瀹�</el-button> + </span> </el-dialog> </div> </template> <script> +import { + addOrUpdateRewardPunishment, deleteRewardPunishment, + rewardPunishmentExport, + rewardPunishmentPage +} from "@/api/cnas/personal/personRewardPunishmentRecord"; +import {selectUserCondition} from "@/api/system/user"; +import {delCustomById} from "@/api/system/customer"; + export default { props: { departId: { @@ -143,6 +162,7 @@ data() { return { tableData: [], + tableLoading: false, search: { size: 20, current: 1, @@ -213,23 +233,23 @@ this.getPersonnelTraining(this.departId); }, async getPersonnelTraining() { - const {code, data} = await this.$axios({ - method: 'get', - url: rewardPunishmentPageApi, - params: { - userId: this.isDepartment ? '' : this.departId, + const params = { + userId: this.isDepartment ? '' : this.departId, departmentId: this.isDepartment ? this.departId : '', current: this.search.curent, size: this.search.size, userName: this.search.userName, startTime: this.search.searchTimeList && this.search.searchTimeList[0], endTime: this.search.searchTimeList && this.search.searchTimeList[1], - } - }) - if (code == 200) { - this.tableData = data.records - this.search.total = data.total } + this.tableLoading = true + rewardPunishmentPage(params).then(res => { + this.tableLoading = false + this.tableData = res.data.records + this.search.total = res.data.total + }).catch(err => { + this.tableLoading = false + }) }, addRow () { this.dialogVisible = true @@ -240,60 +260,28 @@ }, handleDown(){ this.outLoading = true - this.$axios.post(this.$api.deviceCheck.rewardPunishmentExport,{ + rewardPunishmentExport({ userId: this.isDepartment ? '' : this.departId, departmentId: this.isDepartment ? this.departId : '', userName: this.search.userName, startTime: this.search.searchTimeList && this.search.searchTimeList[0], endTime: this.search.searchTimeList && this.search.searchTimeList[1] - },{responseType: 'blob'}).then(res => { + }).then(res => { this.outLoading = false const blob = new Blob([res], { type: 'application/force-download' }) - //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆 - let reader = new FileReader(); - reader.readAsText(blob, 'utf-8'); - reader.onload = () => { - try { - let result = JSON.parse(reader.result); - if (result.message) { - this.$message.error(result.message); - } else { - // 鍒涘缓涓�涓秴閾炬帴锛屽皢鏂囦欢娴佽祴杩涘幓锛岀劧鍚庡疄鐜拌繖涓秴閾炬帴鐨勫崟鍑讳簨浠� - const elink = document.createElement('a') - elink.download = decodeURI('濂栨儵璁板綍'+'.xlsx') - elink.style.display = 'none' - elink.href = URL.createObjectURL(blob) - document.body.appendChild(elink) - elink.click(); - URL.revokeObjectURL(elink.href) // 閲婃斁URL 瀵硅薄 - document.body.removeChild(elink) - this.$message.success('瀵煎嚭鎴愬姛') - } - } catch (err) { - console.log(err); - // 鍒涘缓涓�涓秴閾炬帴锛屽皢鏂囦欢娴佽祴杩涘幓锛岀劧鍚庡疄鐜拌繖涓秴閾炬帴鐨勫崟鍑讳簨浠� - const elink = document.createElement('a') - elink.download = decodeURI('濂栨儵璁板綍'+'.xlsx') - elink.style.display = 'none' - elink.href = URL.createObjectURL(blob) - document.body.appendChild(elink) - elink.click(); - URL.revokeObjectURL(elink.href) // 閲婃斁URL 瀵硅薄 - document.body.removeChild(elink) - this.$message.success('瀵煎嚭鎴愬姛') - } - } + this.$download.saveAs(blob, '濂栨儵璁板綍.xlsx') + this.$message.success('瀵煎嚭鎴愬姛') }) }, // 鑾峰彇璐熻矗浜轰俊鎭帴鍙� getUserList() { - this.$axios.get(this.$api.deviceScope.selectUserList).then(res => { + selectUserCondition().then(res => { if (res.code == 200) { this.responsibleOptions = res.data } - }) + }); }, selectUserChange(val) { const index = this.responsibleOptions.findIndex(item => item.id === val) @@ -302,42 +290,40 @@ this.form.account = this.responsibleOptions[index].account } }, + // 鎵撳紑琛ㄥ崟寮规 editForm(row) { this.dialogVisible = true this.form = {...row}; }, + // 鎻愪氦琛ㄥ崟鏁版嵁 saveOrUpdate() { this.$refs.form.validate(async (valid) => { if (valid) { - this.dialogVisible = false - const {code, data} = await this.$axios({ - method: 'post', - url: addOrUpdateRewardPunishmentApi, - data: this.form, - headers: { - 'Content-Type': 'application/json' - }, - noQs: true - }) - if (code == 200) { - this.$message.success("鎿嶄綔鎴愬姛锛�") + addOrUpdateRewardPunishment(this.form).then(res => { + this.dialogVisible = false + this.$message.success("鎿嶄綔鎴愬姛") this.getPersonnelTraining(this.departId); - } + }) } }) }, - async deleteRow(row) { - const {code, data} = await this.$axios({ - method: 'delete', - url: deleteRewardPunishmentApi, - params: { - id: row.id - } - }) - if (code == 200) { - this.$message.success("鎿嶄綔鎴愬姛锛�") - this.getPersonnelTraining(this.departId); - } + deleteRow(row) { + this.$confirm('鏄惁鍒犻櫎褰撳墠鏁版嵁?', "璀﹀憡", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning" + }).then(() => { + deleteRewardPunishment({id: row.id}).then(res => { + if (res.code === 500) { + return + } + this.$message.success('鍒犻櫎鎴愬姛') + this.getPersonnelTraining(this.departId); + }).catch(e => { + this.$message.error('鍒犻櫎澶辫触') + }) + }).catch(() => {}) + } }, watch: { diff --git a/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue b/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue index 6ac536f..a2642b7 100644 --- a/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue +++ b/src/views/CNAS/personnel/personnelInfo/tabs/training-record.vue @@ -2,82 +2,54 @@ <template> <div> <div class="flex_table"> - <div v-if="isDepartment" style="width: 50%"> -<!-- <TableCard :showTitle="false">--> -<!-- <template v-slot:form>--> -<!-- <div class="items_center">--> -<!-- <span>濮撳悕</span>--> -<!-- <el-input v-model="trainingPagination.userName" class="search" clearable placeholder="璇疯緭鍏�" size="small"></el-input>--> -<!-- <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button>--> -<!-- </div>--> -<!-- <div>--> -<!--<!– <el-button :loading="outLoading" size="small" type="primary" @click="exportExcel">瀵煎嚭</el-button>–>--> -<!-- </div>--> -<!-- </template>--> -<!-- <template v-slot:table>--> -<!-- <ZTTable--> -<!-- :column="trainingColumn"--> -<!-- :currentChange="currentChange"--> -<!-- :height="'calc(100vh - 18em)'"--> -<!-- :highlightCurrentRow="true"--> -<!-- :table-data="trainingTableData"--> -<!-- :table-loading="trainingLoading"--> -<!-- style="padding: 0 15px;">--> -<!-- </ZTTable>--> -<!-- <div class="pagination">--> -<!-- <div></div>--> -<!-- <el-pagination--> -<!-- :page-size="trainingPagination.size"--> -<!-- :page-sizes="[10, 20, 30, 40]"--> -<!-- :total="trainingPagination.total"--> -<!-- layout="total, sizes, prev, pager, next, jumper"--> -<!-- @current-change="handleYearCurrentTraining"--> -<!-- @size-change="handleYearSizeChangeTraining">--> -<!-- </el-pagination>--> -<!-- </div>--> -<!-- </template>--> -<!-- </TableCard>--> -<!-- </div>--> -<!-- <div :style="`width: ${isDepartment ? '50%' : '100%'};`">--> -<!-- <TableCard :showTitle="false">--> -<!-- <template v-slot:form>--> -<!-- <div class="items_center">--> -<!-- <span>骞翠唤</span>--> -<!-- <el-date-picker--> -<!-- v-model="searchForm.trainingDate"--> -<!-- clearable--> -<!-- format="yyyy"--> -<!-- placeholder="閫夋嫨骞�"--> -<!-- size="small"--> -<!-- style="margin: 0 10px"--> -<!-- type="year"--> -<!-- value-format="yyyy">--> -<!-- </el-date-picker>--> -<!-- <el-button size="small" type="primary" @click="queryPersonnelDetailsPage(currentChangeRow.userId)">鏌ヨ</el-button>--> -<!-- <el-button size="small" type="primary" @click="openDownloadDia(currentChangeRow)">瀵煎嚭</el-button>--> -<!-- </div>--> -<!-- </template>--> -<!-- <template v-slot:table>--> -<!-- <ZTTable--> -<!-- :column="trainingPersonColumn"--> -<!-- :height="'calc(100vh - 18em)'"--> -<!-- :table-data="trainingPersonTableData"--> -<!-- :table-loading="trainingPersonLoading"--> -<!-- style="padding: 0 15px;">--> -<!-- </ZTTable>--> -<!-- <div class="pagination">--> -<!-- <div></div>--> -<!-- <el-pagination--> -<!-- :page-size="trainingPersonPagination.size"--> -<!-- :page-sizes="[10, 20, 30, 40]"--> -<!-- :total="trainingPersonPagination.total"--> -<!-- layout="total, sizes, prev, pager, next, jumper"--> -<!-- @current-change="handleYearCurrentPagination"--> -<!-- @size-change="handleYearSizeChangePagination">--> -<!-- </el-pagination>--> -<!-- </div>--> -<!-- </template>--> -<!-- </TableCard>--> + <div v-if="isDepartment" style="width: 49%"> + <div class="title"> + <span style="font-weight: bold">骞村害璁″垝</span> + </div> + <div style="display: flex;justify-content: space-between;"> + <el-form :model="trainingPagination" ref="trainingPagination" size="small" :inline="true"> + <el-form-item label="濮撳悕"> + <el-input v-model="trainingPagination.userName" class="search" clearable placeholder="璇疯緭鍏�" size="small"></el-input> + </el-form-item> + <el-form-item> + <el-button size="small" type="primary" @click="getPersonnelTraining(departId)">鏌ヨ</el-button> + </el-form-item> + </el-form> + </div> + <lims-table :tableData="trainingTableData" :column="trainingColumn" + ref="trainingTableData" + :currentChange="currentChange" :highlightCurrentRow="true" + @pagination="pagination" :height="'calc(100vh - 22em)'" + :page="trainingPagination" :tableLoading="trainingLoading"></lims-table> + </div> + <div :style="`width: ${isDepartment ? '49%' : '100%'};`"> + <div class="title"> + <span style="font-weight: bold">骞村害璁″垝鏄庣粏</span> + </div> + <div style="display: flex;justify-content: space-between;"> + <el-form :model="searchForm" ref="searchForm" size="small" :inline="true"> + <el-form-item label="骞翠唤"> + <el-date-picker + v-model="searchForm.trainingDate" + clearable + format="yyyy" + placeholder="閫夋嫨骞�" + size="small" + type="year" + value-format="yyyy"> + </el-date-picker> + </el-form-item> + <el-form-item> + <el-button size="small" type="primary" @click="queryPersonnelDetailsPage(currentChangeRow.userId)">鏌ヨ</el-button> + </el-form-item> + </el-form> + <div> + <el-button size="small" type="primary" @click="openDownloadDia(currentChangeRow)">瀵煎嚭</el-button> + </div> + </div> + <lims-table :tableData="trainingPersonTableData" :column="trainingPersonColumn" + :height="'calc(100vh - 22em)'" @pagination="pagination1" + :page="trainingPersonPagination" :tableLoading="trainingPersonLoading"></lims-table> </div> </div> </div> @@ -85,8 +57,15 @@ <script> +import limsTable from "@/components/Table/lims-table.vue"; +import { + exportTrainingRecord, + queryPersonnelDetails, + trainingSelectTrainingRecord +} from "@/api/cnas/personal/personTrainingRecord"; + export default { - components: {}, + components: {limsTable}, props: { departId: { type: Number, @@ -215,48 +194,31 @@ if (!date) { date = this.$moment().format('YYYY') } - console.log('date----', date); - this.$axios.get( this.$api.personnel.exportTrainingRecord+ '?userId=' + row.userId + '&trainingDate=' + date,{responseType: "blob"}).then(res => { + exportTrainingRecord({userId: row.userId, trainingDate: date}).then(res => { this.outLoading = false const blob = new Blob([res],{ type: 'application/msword' }); - //灏咮lob 瀵硅薄杞崲鎴愬瓧绗︿覆 - let reader = new FileReader(); - reader.readAsText(blob, 'utf-8'); - reader.onload = () => { - try { - let result = JSON.parse(reader.result); - if (result.message) { - this.$message.error(result.message); - } else { - const url = URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = url; - link.download = '鍩硅璁板綍瀵煎嚭' + '.docx'; - link.click(); - this.$message.success('瀵煎嚭鎴愬姛') - } - } catch (err) { - console.log(err); - const url = URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = url; - link.download = '鍩硅璁板綍瀵煎嚭' + '.docx'; - link.click(); - this.$message.success('瀵煎嚭鎴愬姛') - } - } + this.$download.saveAs(blob, '鍩硅璁板綍瀵煎嚭.docx'); }) }, // 鑾峰彇瀹為獙瀹�-鍩硅璁″垝鍒楄〃淇℃伅 getPersonnelTraining(departId) { - // const name = this.isDepartment ? 'departmentId' : 'userId'; - this.$axios.get(`${this.$api.personnel.trainingSelectTrainingRecord}?departmentId=${departId}&size=${this.trainingPagination.size}¤t=${this.trainingPagination.current}&userName=${this.trainingPagination.userName}`).then(res => { + const params = { + departmentId: departId, + size: this.trainingPagination.size, + current: this.trainingPagination.current, + userName: this.trainingPagination.userName, + } + this.trainingLoading = true + trainingSelectTrainingRecord(params).then(res => { + this.trainingLoading = false this.trainingTableData = res.data.records; this.trainingPagination.total = res.data.total; if (this.trainingTableData.length > 0) { - this.currentChange(this.trainingTableData[0]); + this.$refs.trainingTableData.setCurrentRow(this.trainingTableData[0]) } - }); + }).catch(err => { + this.trainingLoading = false + }) }, // 鑾峰彇涓汉-鍩硅璁″垝鍒楄〃淇℃伅 currentChange(row) { @@ -270,29 +232,31 @@ if (this.searchForm.trainingDate === null) { this.searchForm.trainingDate = '' } - this.$axios.get(`${this.$api.personnel.queryPersonnelDetails}?userId=${userId}&size=${this.trainingPersonPagination.size}¤t=${this.trainingPersonPagination.current}&trainingDate=${this.searchForm.trainingDate}`).then(res => { + const params = { + userId: userId, + size: this.trainingPersonPagination.size, + current: this.trainingPersonPagination.current, + trainingDate: this.searchForm.trainingDate, + } + this.trainingPersonLoading = true + queryPersonnelDetails(params).then(res => { + this.trainingPersonLoading = false this.trainingPersonTableData = res.data.records; this.trainingPersonPagination.total = res.data.total; - }); + }).catch(err => { + this.trainingPersonLoading = false + }) }, // 鍒嗛〉 - handleYearCurrentTraining(page) { - this.trainingPagination.curent = page; - this.getPersonnelTraining(this.departId); - }, - handleYearSizeChangeTraining(size) { - this.trainingPagination.size = size; + pagination(page) { + this.trainingPagination.size = page.limit; this.getPersonnelTraining(this.departId); }, // 鍒嗛〉 - handleYearCurrentPagination(page) { - this.trainingPersonPagination.curent = page; + pagination1(page) { + this.trainingPersonPagination.size = page.limit; this.queryPersonnelDetailsPage(this.currentChangeRow.userId); }, - handleYearSizeChangePagination(size) { - this.trainingPersonPagination.size = size; - this.queryPersonnelDetailsPage(this.currentChangeRow.userId); - } }, watch: { departId: { @@ -308,29 +272,32 @@ }; </script> <style scoped> ->>> .el-form-item { - margin-bottom: 13px; -} - .flex_table { display: flex; flex-direction: row; justify-content: space-between; } -.pagination { - display: flex; - justify-content: space-between; - margin-top: 10px; -} - -.items_center { - display: flex; - align-items: center; -} - .search { width: 150px; - padding: 0 6px; +} +.title { + position: relative; + font-size: 16px; + color: #333; + font-weight: 400; + padding-left: 10px; + margin-bottom: 10px; +} + +.title::before { + position: absolute; + left: 0; + top: 4px; + content: ''; + width: 4px; + height: 16px; + background-color: #3A7BFA; + border-radius: 2px; } </style> -- Gitblit v1.9.3