|
@@ -0,0 +1,437 @@
|
|
|
+<template>
|
|
|
+ <div class="container add-new-entries">
|
|
|
+ <div class="container-top">
|
|
|
+ <span>客户名称</span>
|
|
|
+ <el-autocomplete v-model="companyName" :fetch-suggestions="querySearchAsync" style="width: 220px; margin: 0 20px" @select="selectCompanyChange" placeholder="请输入客户名称"></el-autocomplete>
|
|
|
+
|
|
|
+ <div class="quarters-content">
|
|
|
+ <el-checkbox-group v-model="selectedQuarters">
|
|
|
+ <el-checkbox v-for="quarter in quarters" :key="quarter.value" :label="quarter.label" :disabled="isDisabled(quarter)">
|
|
|
+ {{ quarter.label }}
|
|
|
+ </el-checkbox>
|
|
|
+ </el-checkbox-group>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="Object.keys(EnterScoreObj).length > 0">
|
|
|
+ <div class="tabs-box">
|
|
|
+ <span v-for="item in listTitle" :key="item.value" @click="tabsBoxBtn(item)" :class="item.value == tabsPitchon ? 'pitch' : ''">{{ item.lable }}</span>
|
|
|
+ </div>
|
|
|
+ <template>
|
|
|
+ <p class="class-text">
|
|
|
+ 权益研究员 <span style="font-weight: 600">{{ allPerCentNumble(raiDataHandler(), "rai") }}</span>
|
|
|
+ <span v-if="tabsPitchon == 2 && allPerCentNumble(raiDataHandler(), 'rai')">%</span>
|
|
|
+ </p>
|
|
|
+ <div class="content-box">
|
|
|
+ <div v-for="item in raiDataHandler()" :key="item.EnterScoreId">
|
|
|
+ <div :class="['industry-ul']">
|
|
|
+ <span :class="['industry-name']">{{ item.ChartPermissionName }}</span>
|
|
|
+ <span style="margin: 0 5px 0 8px; font-weight: 600">{{ allPerCentHandlerRai(item) }}</span>
|
|
|
+ <span v-if="tabsPitchon == 2 && item.Proportion">%</span>
|
|
|
+ </div>
|
|
|
+ <div v-for="study in item.List" :key="study.RealName" :class="['industry-ul']">
|
|
|
+ <span :class="['study-name']">{{ study.RealName }}</span>
|
|
|
+ <template>
|
|
|
+ <el-input :min="-100" :max="100" type="number" v-model="study.Proportion" size="small" @input="formatDecimal(study)" style="width: 76px; margin: 0 5px 0 8px"> </el-input>
|
|
|
+ </template>
|
|
|
+ <span v-if="tabsPitchon == 2">%</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template>
|
|
|
+ <p class="class-text">
|
|
|
+ FICC研究员 <span style="font-weight: 600">{{ allPerCentNumble(FICCDataHandler(), "ficc") }}</span>
|
|
|
+ <span v-if="tabsPitchon == 2 && allPerCentNumble(FICCDataHandler(), 'ficc')">%</span>
|
|
|
+ </p>
|
|
|
+ <div class="content-box">
|
|
|
+ <div v-for="item in FICCDataHandler()" :key="item.EnterScoreId">
|
|
|
+ <div :class="['industry-ul']">
|
|
|
+ <span :class="['industry-name']">{{ item.ChartPermissionName }}</span>
|
|
|
+ <span style="margin: 0 5px 0 8px; font-weight: 600">{{ allPerCentHandlerFICC(item) }}</span>
|
|
|
+ <span v-if="tabsPitchon == 2 && item.Proportion">%</span>
|
|
|
+ </div>
|
|
|
+ <div v-for="study in item.List" :key="study.RealName" :class="['industry-ul']">
|
|
|
+ <span :class="['study-name']">{{ study.RealName }}</span>
|
|
|
+ <template>
|
|
|
+ <el-input :min="-100" :max="100" type="number" v-model="study.Proportion" size="small" @input="formatDecimal(study)" style="width: 76px; margin: 0 5px 0 8px"> </el-input>
|
|
|
+ </template>
|
|
|
+ <span v-if="tabsPitchon == 2">%</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="division-line"></div>
|
|
|
+ <div class="content-box">
|
|
|
+ <div v-for="item in ProuDataHandler()" :key="item.GroupName">
|
|
|
+ <div :class="['industry-ul']">
|
|
|
+ <span :class="['industry-name']">{{ item.GroupName }}</span>
|
|
|
+ <el-input :min="-100" :max="100" type="number" v-model="item.Proportion" @input="formatDecimal(item)" size="small" style="width: 76px; margin: 0 5px 0 8px"> </el-input>
|
|
|
+ <span v-if="tabsPitchon == 2">%</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="division-line"></div>
|
|
|
+ <div class="bottom-box">
|
|
|
+ 排名
|
|
|
+ <el-input type="text" v-model="rankingValue" style="width: 110px; margin: 0 50px 0 8px" placeholder="请输入排名"> </el-input>
|
|
|
+ 合并打分
|
|
|
+ <el-radio-group v-model="radioScoring" style="margin: 0 60px 0 8px">
|
|
|
+ <el-radio :label="0">否</el-radio>
|
|
|
+ <el-radio :label="1">是</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ <template v-if="radioScoring == 1">
|
|
|
+ 券商名称
|
|
|
+ <el-input type="text" v-model="brokerName" placeholder="请输入合并打分的券商名称" style="width: 230px; margin: 0 50px 0 8px"> </el-input>
|
|
|
+ 合并占比
|
|
|
+ <el-input type="text" v-model="mergeProportion" placeholder="占比值" style="width: 76px; margin: 0 5px 0 8px"> </el-input>%
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <p class="total-num" v-if="Object.keys(EnterScoreObj).length > 0">
|
|
|
+ 当前合计总分:{{ TotalScoreHandler(ProuDataHandler()) }}
|
|
|
+ <span v-if="tabsPitchon == 2">%</span>
|
|
|
+ </p>
|
|
|
+ <div style="display: flex; justify-content: center">
|
|
|
+ <el-button type="primary" style="margin-right: 20px" @click="preserveHandler">{{ $route.query.id ? "修改并保存" : "保存" }}</el-button>
|
|
|
+ <el-button type="primary" plain @click="goBackHandler">取消</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import quartersMixin from "../customList/mixins/quartersMixin";
|
|
|
+import { xClassCustomApi, raiInterface } from "@/api/api.js";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "",
|
|
|
+ components: {},
|
|
|
+ mixins: [quartersMixin],
|
|
|
+ props: {},
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ listTitle: [
|
|
|
+ {
|
|
|
+ lable: "按评分录入",
|
|
|
+ value: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ lable: "按比例录入",
|
|
|
+ value: 2,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ tabsPitchon: 1, //tabs 默认选中
|
|
|
+ tmeplateObj: {},
|
|
|
+ EnterScoreObj: {},
|
|
|
+ PercentageObj: {},
|
|
|
+ rankingValue: "", // 排名
|
|
|
+ radioScoring: 0, // 合并打分
|
|
|
+ brokerName: "", //券商名称
|
|
|
+ mergeProportion: "",
|
|
|
+ querySearchList: [],
|
|
|
+ companyName: "",
|
|
|
+ companyId: 0,
|
|
|
+ totalScoreNumber: 0,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {},
|
|
|
+ watch: {
|
|
|
+ companyName: {
|
|
|
+ handler(newVal) {
|
|
|
+ if (!this.companyName) {
|
|
|
+ this.companyId = 0;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created() {},
|
|
|
+ mounted() {
|
|
|
+ this.$route.query.id ? this.getCompanyDetail() : this.getDataTemplate();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 头部的点击事件
|
|
|
+ tabsBoxBtn(item) {
|
|
|
+ if (this.tabsPitchon == item.value) return;
|
|
|
+ this.tabsPitchon = item.value;
|
|
|
+ this.raiDataHandler();
|
|
|
+ this.FICCDataHandler();
|
|
|
+ this.ProuDataHandler();
|
|
|
+ },
|
|
|
+
|
|
|
+ /** */
|
|
|
+ /** */
|
|
|
+ allPerCentHandlerRai(item) {
|
|
|
+ return this.allPerCentHandler(item);
|
|
|
+ },
|
|
|
+ allPerCentHandlerFICC(item) {
|
|
|
+ return this.allPerCentHandler(item);
|
|
|
+ },
|
|
|
+ //数量的总和
|
|
|
+ allPerCentHandler(item) {
|
|
|
+ let num = 0;
|
|
|
+ item && item.List.forEach((key) => (num = num + +key.Proportion));
|
|
|
+ item.Proportion = Number(num.toFixed(2));
|
|
|
+ return num == 0 ? "" : num.toFixed(2);
|
|
|
+ },
|
|
|
+ /** */
|
|
|
+ /** */
|
|
|
+
|
|
|
+ // 处理小数点
|
|
|
+ formatDecimal(key) {
|
|
|
+ let value = key.Proportion;
|
|
|
+ if (value === "") return; // 如果为空则不处理
|
|
|
+ // 先清除非数字和多余的小数点
|
|
|
+ value = value
|
|
|
+ .replace(/[^\d.]/g, "")
|
|
|
+ .replace(/\.{2,}/g, ".")
|
|
|
+ .replace(".", "$#$")
|
|
|
+ .replace(/\./g, "")
|
|
|
+ .replace("$#$", ".");
|
|
|
+
|
|
|
+ // 限制只能输入两位小数
|
|
|
+ const decimalRegex = /^(\d+\.?\d{0,2})/;
|
|
|
+ const match = value.match(decimalRegex);
|
|
|
+
|
|
|
+ if (match) {
|
|
|
+ key.Proportion = match[1];
|
|
|
+ this.restrictInput(key);
|
|
|
+ } else {
|
|
|
+ key.Proportion = 0; // 如果不匹配正则,则清空输入框
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 输入框的限制
|
|
|
+ restrictInput(item) {
|
|
|
+ if (item.Proportion) if (item.Proportion > 100) return (item.Proportion = 100);
|
|
|
+ if (item.Proportion < -100) return (item.Proportion = -100);
|
|
|
+ },
|
|
|
+ // 切换了录入 权益
|
|
|
+ raiDataHandler() {
|
|
|
+ return this.tabsPitchon == 1 ? this.EnterScoreObj.ListRai : this.PercentageObj.ListRai;
|
|
|
+ },
|
|
|
+ // 切换了录入 FICC
|
|
|
+ FICCDataHandler() {
|
|
|
+ return this.tabsPitchon == 1 ? this.EnterScoreObj.ListFicc : this.PercentageObj.ListFicc;
|
|
|
+ },
|
|
|
+ // 切换了录入 分组
|
|
|
+ ProuDataHandler() {
|
|
|
+ return this.tabsPitchon == 1 ? this.EnterScoreObj.ListGroup : this.PercentageObj.ListGroup;
|
|
|
+ },
|
|
|
+
|
|
|
+ /** */
|
|
|
+ /** */
|
|
|
+ // 总和
|
|
|
+ allPerCentNumble(item, type) {
|
|
|
+ let num = 0;
|
|
|
+ item.forEach((item) => (num += item.Proportion));
|
|
|
+ type === "rai" ? (this.tmeplateObj.RaiProportionTotal = Number(num.toFixed(2))) : (this.tmeplateObj.FiccProportionTotal = Number(num.toFixed(2)));
|
|
|
+ return num == 0 ? "" : num.toFixed(2);
|
|
|
+ },
|
|
|
+ TotalScoreHandler(item) {
|
|
|
+ let num = 0;
|
|
|
+ item && item.forEach((item) => (num += Number(item.Proportion)));
|
|
|
+ this.totalScoreNumber = Number((num + this.tmeplateObj.RaiProportionTotal + this.tmeplateObj.FiccProportionTotal).toFixed(2));
|
|
|
+ return this.totalScoreNumber;
|
|
|
+ },
|
|
|
+ /** */
|
|
|
+ /** */
|
|
|
+
|
|
|
+ // 获取模板
|
|
|
+ async getDataTemplate() {
|
|
|
+ const res = await xClassCustomApi.enterScoreDetail();
|
|
|
+ if (res.Ret === 200) {
|
|
|
+ this.tmeplateObj = res.Data;
|
|
|
+ this.EnterScoreObj = res.Data.EnterScoreObj;
|
|
|
+ this.PercentageObj = res.Data.PercentageObj;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 保存
|
|
|
+ async preserveHandler() {
|
|
|
+ let StartDate = this.selectedDateRange ? this.selectedDateRange.split(" ~ ")[0] : "";
|
|
|
+ let EndDate = this.selectedDateRange ? this.selectedDateRange.split(" ~ ")[1] : "";
|
|
|
+ let ListGroup = this.ProuDataHandler().map((item) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ Proportion: Number(item.Proportion),
|
|
|
+ };
|
|
|
+ });
|
|
|
+ let ListRai = this.raiDataHandler().map((item) => ({
|
|
|
+ ...item,
|
|
|
+ List: item.List.map((subItem) => ({
|
|
|
+ ...subItem,
|
|
|
+ Proportion: Number(subItem.Proportion),
|
|
|
+ })),
|
|
|
+ }));
|
|
|
+ let ListFicc = this.FICCDataHandler().map((item) => ({
|
|
|
+ ...item,
|
|
|
+ List: item.List.map((subItem) => ({
|
|
|
+ ...subItem,
|
|
|
+ Proportion: Number(subItem.Proportion),
|
|
|
+ })),
|
|
|
+ }));
|
|
|
+ let params = {
|
|
|
+ EnterScoreId: this.$route.query.id ? +this.$route.query.id : 0, //录分ID,等于0新增,大于0 修改
|
|
|
+ CompanyId: this.companyId,
|
|
|
+ CompanyName: this.companyName,
|
|
|
+ Quarter: this.selectedQuarters,
|
|
|
+ StartDate,
|
|
|
+ EndDate,
|
|
|
+ EnterScoreType: this.tabsPitchon,
|
|
|
+ RaiProportionTotal: this.tmeplateObj.RaiProportionTotal,
|
|
|
+ FiccProportionTotal: this.tmeplateObj.FiccProportionTotal,
|
|
|
+ ListRai,
|
|
|
+ ListFicc,
|
|
|
+ ListGroup,
|
|
|
+ Ranking: this.rankingValue,
|
|
|
+ IsMergeScoring: this.radioScoring,
|
|
|
+ SecuritiesFirmsName: this.brokerName,
|
|
|
+ MergeProportion: this.mergeProportion ? +this.mergeProportion : 0,
|
|
|
+ ProportionTotal: this.totalScoreNumber,
|
|
|
+ };
|
|
|
+ if (!params.CompanyName || !params.CompanyId) return this.$message.error("请输入客户名称");
|
|
|
+ if (!params.Quarter.length) return this.$message.error("请选择季度");
|
|
|
+ const res = await xClassCustomApi.enterScoreUpdate(params);
|
|
|
+ if (res.Ret === 200) {
|
|
|
+ this.$message.success(res.Msg);
|
|
|
+ this.$router.back();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取详情
|
|
|
+ async getCompanyDetail() {
|
|
|
+ const res = await xClassCustomApi.enterScoreDetail({
|
|
|
+ EnterScoreId: +this.$route.query.id,
|
|
|
+ });
|
|
|
+ if (res.Ret === 200) {
|
|
|
+ this.tmeplateObj = res.Data;
|
|
|
+ this.EnterScoreObj = res.Data.EnterScoreObj;
|
|
|
+ this.PercentageObj = res.Data.PercentageObj;
|
|
|
+ this.rankingValue = res.Data.Ranking;
|
|
|
+ this.radioScoring = res.Data.IsMergeScoring;
|
|
|
+ this.brokerName = res.Data.SecuritiesFirmsName;
|
|
|
+ this.mergeProportion = res.Data.MergeProportion;
|
|
|
+ this.selectedQuarters = res.Data.Quarter;
|
|
|
+ this.companyId = res.Data.CompanyId;
|
|
|
+ this.companyName = res.Data.CompanyName;
|
|
|
+ this.tabsPitchon = res.Data.EnterScoreType;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //
|
|
|
+ async querySearchAsync(query, cb) {
|
|
|
+ cb([]);
|
|
|
+ if (query) {
|
|
|
+ const res = await xClassCustomApi.enterScoreSearchlist({ KeyWord: query });
|
|
|
+ if (res.Ret === 200) {
|
|
|
+ this.querySearchList = res.Data.List.map((_) => {
|
|
|
+ return {
|
|
|
+ ..._,
|
|
|
+ value: _.CompanyName,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ cb(this.querySearchList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 选择后客户名称的id
|
|
|
+ selectCompanyChange(value) {
|
|
|
+ this.companyId = value.CompanyId;
|
|
|
+ },
|
|
|
+ // 返回事件
|
|
|
+ goBackHandler() {
|
|
|
+ this.$router.back();
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style scoped lang="scss">
|
|
|
+.add-new-entries {
|
|
|
+ .container-top {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .class-text {
|
|
|
+ margin-top: 20px;
|
|
|
+ width: 100%;
|
|
|
+ height: 38px;
|
|
|
+ line-height: 32px;
|
|
|
+ padding-left: 20px;
|
|
|
+ background-color: #ebeef5;
|
|
|
+ }
|
|
|
+ .tabs-box {
|
|
|
+ margin-top: 20px;
|
|
|
+ span {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 9px 24px;
|
|
|
+ background-color: #e9f4ff;
|
|
|
+ border: 1px solid #b3d8ff;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-right: 30px;
|
|
|
+ color: #409eff;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .pitch {
|
|
|
+ background-color: #409eff;
|
|
|
+ border: none;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .content-box {
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ overflow-x: auto;
|
|
|
+ display: flex;
|
|
|
+ .industry-ul {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin: 10px 0;
|
|
|
+ width: 188px;
|
|
|
+ color: #333;
|
|
|
+ margin-right: 25px;
|
|
|
+ .per_cent_ {
|
|
|
+ line-height: 32px;
|
|
|
+ }
|
|
|
+ .industry-name {
|
|
|
+ flex-shrink: 0;
|
|
|
+ font-weight: 800;
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 22px;
|
|
|
+ }
|
|
|
+ .study-name {
|
|
|
+ width: 58px;
|
|
|
+ flex-shrink: 0;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 22px;
|
|
|
+ }
|
|
|
+ p {
|
|
|
+ color: #9999;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .division-line {
|
|
|
+ width: 100%;
|
|
|
+ border: 1px dashed #dcdfe6;
|
|
|
+ margin: 30px 0 20px;
|
|
|
+ }
|
|
|
+ .bottom-box {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .total-num {
|
|
|
+ margin: 30px 0 20px 0;
|
|
|
+ padding-left: 460px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style>
|
|
|
+/* 针对于 Chrome、Safari 等 Webkit 内核浏览器 */
|
|
|
+input[type="number"]::-webkit-inner-spin-button,
|
|
|
+input[type="number"]::-webkit-outer-spin-button {
|
|
|
+ -webkit-appearance: none;
|
|
|
+ margin: 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* 针对 Firefox 浏览器 */
|
|
|
+input[type="number"] {
|
|
|
+ -moz-appearance: textfield;
|
|
|
+}
|
|
|
+</style>
|