|
|
@@ -1,13 +1,502 @@
|
|
|
<template>
|
|
|
- <div>
|
|
|
- 积分规则
|
|
|
+ <div class="integration-rule-page">
|
|
|
+ <div class="section-box">
|
|
|
+ <div class="section-title">积分生成规则</div>
|
|
|
+ <el-table :data="ruleData" border style="width: 100%">
|
|
|
+ <el-table-column prop="remarks" label="规则名称" min-width="200" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="value" label="积分" width="200" align="center" />
|
|
|
+ <!-- <el-table-column label="操作" width="120" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button type="text" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column> -->
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="section-box mt-16">
|
|
|
+ <div class="section-title">积分规则编辑器</div>
|
|
|
+ <el-table :data="editorData" border>
|
|
|
+ <el-table-column label="工单模版" width="180" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select
|
|
|
+ v-model="scope.row.sc_workorder_templateid"
|
|
|
+ placeholder="请选择"
|
|
|
+ size="small"
|
|
|
+ :disabled="!scope.row.isNew"
|
|
|
+ @change="handleWorkOrderTypeChange(scope.$index, scope.row)"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in workOrderTypeList"
|
|
|
+ :key="item.sc_workorder_templateid"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.sc_workorder_templateid"
|
|
|
+ ></el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="A积分规则" align="center">
|
|
|
+ <el-table-column label="团队定位" width="120" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.a_team" placeholder="请选择" size="small">
|
|
|
+ <el-option label="组长" value="组长"></el-option>
|
|
|
+ <el-option label="技师" value="技师"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="符号" width="80" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.a_symbol" size="small">
|
|
|
+ <el-option label="=" value="="></el-option>
|
|
|
+ <el-option label=">" value=">"></el-option>
|
|
|
+ <el-option label="≥" value="≥"></el-option>
|
|
|
+ <el-option label="<" value="<"></el-option>
|
|
|
+ <el-option label="≤" value="≤"></el-option>
|
|
|
+ <el-option label="≠" value="≠"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="人数" width="160" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-input v-model="scope.row.a_count" size="small" placeholder="请输入" oninput="value = value.replace(/[^\d]/g, '')"></el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="积分占比(%)" width="160" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-input v-model="scope.row.a_ratio" size="small" placeholder="0-100" oninput="value = value.replace(/[^\d]/g, ''); if(value>100)value=100"></el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="C积分规则" align="center">
|
|
|
+ <el-table-column label="团队定位" width="160" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.c_team" placeholder="请选择" size="small">
|
|
|
+ <el-option label="组长" value="组长"></el-option>
|
|
|
+ <el-option label="技师" value="技师"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="符号" width="80" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-select v-model="scope.row.c_symbol" size="small">
|
|
|
+ <el-option label="=" value="="></el-option>
|
|
|
+ <el-option label=">" value=">"></el-option>
|
|
|
+ <el-option label="≥" value="≥"></el-option>
|
|
|
+ <el-option label="<" value="<"></el-option>
|
|
|
+ <el-option label="≤" value="≤"></el-option>
|
|
|
+ <el-option label="≠" value="≠"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="人数" width="160" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-input v-model="scope.row.c_count" size="small" placeholder="请输入" oninput="value = value.replace(/[^\d]/g, '')"></el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="积分占比(%)" width="160" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-input v-model="scope.row.c_ratio" size="small" placeholder="0-100" oninput="value = value.replace(/[^\d]/g, ''); if(value>100)value=100"></el-input>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button type="text" size="small" @click="handleEditorSave(scope.$index)">保存</el-button>
|
|
|
+ <!-- <el-button type="text" size="small" @click="handleEditorDelete(scope.$index)">删除</el-button> -->
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div class="editor-footer">
|
|
|
+ <el-button type="primary" size="small" @click="handleAddRow">新增行</el-button>
|
|
|
+ <el-button size="small" @click="fetchEditorData">刷新</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="section-box mt-16">
|
|
|
+ <div class="section-title">积分规则结果列表</div>
|
|
|
+ <el-table :data="mergedRuleData" border style="width: 100%" :span-method="objectSpanMethod">
|
|
|
+ <el-table-column prop="rowindex" width="80" label="序号" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="workOrderTypeName" width="150" label="工单模版" show-overflow-tooltip />
|
|
|
+ <el-table-column label="A积分规则" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.aRuleText }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="C积分规则" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.cRuleText }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="120" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button type="text" size="small" @click="handleResultEdit(scope.row)">编辑</el-button>
|
|
|
+ <el-button type="text" size="small" @click="handleResultDelete(scope.row)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-dialog :visible.sync="dialogVisible" title="编辑积分规则" width="400px">
|
|
|
+ <el-form label-width="100px">
|
|
|
+ <el-form-item label="规则名称">
|
|
|
+ <el-input v-model="editForm.remarks" disabled></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="积分">
|
|
|
+ <el-input-number v-model="editForm.value" :min="0" controls-position="right"></el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="handleSave">保存</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
export default {
|
|
|
-
|
|
|
-}
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ ruleData: [],
|
|
|
+ dialogVisible: false,
|
|
|
+ editForm: {
|
|
|
+ remarks: "",
|
|
|
+ value: 0
|
|
|
+ },
|
|
|
+ editorData: [],
|
|
|
+ workOrderTypeList: [],
|
|
|
+ isLoading: false,
|
|
|
+ resultListData: []
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ mergedRuleData() {
|
|
|
+ const map = {};
|
|
|
+ this.resultListData.forEach((item) => {
|
|
|
+ if (!item.sc_workorder_templateid) return;
|
|
|
+ const key = `${item.sc_workorder_templateid}_${item.rowindex || item.sc_points_rulesmxid}`;
|
|
|
+ if (!map[key]) {
|
|
|
+ map[key] = {
|
|
|
+ rowindex: item.rowindex,
|
|
|
+ sc_points_rulesmxid: item.sc_points_rulesmxid,
|
|
|
+ sc_workorder_templateid: item.sc_workorder_templateid,
|
|
|
+ workOrderTypeName: item.templatename || "",
|
|
|
+ a_team: item.a_position || "",
|
|
|
+ a_symbol: item.a_symbol || "",
|
|
|
+ a_count: item.a_count || 0,
|
|
|
+ a_ratio: item.a_ratio || 0,
|
|
|
+ c_team: item.c_position || "",
|
|
|
+ c_symbol: item.c_symbol || "",
|
|
|
+ c_count: item.c_count || 0,
|
|
|
+ c_ratio: item.c_ratio || 0
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return Object.values(map).map((item) => {
|
|
|
+ const aText = `${item.a_team}${item.a_symbol}${item.a_count}人,积分占比:${item.a_ratio}%`;
|
|
|
+ const cText = `${item.c_team}${item.c_symbol}${item.c_count}人,积分占比:${item.c_ratio}%`;
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ aRuleText: item.a_count > 1 ? `${aText}(均摊)` : aText,
|
|
|
+ cRuleText: item.c_count > 1 ? `${cText}(均摊)` : cText
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.fetchRuleData();
|
|
|
+ this.getWorkOrderTypeList();
|
|
|
+ this.fetchResultListData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ async fetchRuleData() {
|
|
|
+ const res = await this.$store.dispatch("optiontypeselect", "bathroomprepoints");
|
|
|
+ if (res && res.data) {
|
|
|
+ this.ruleData = res.data;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleEdit(row) {
|
|
|
+ this.editForm = {
|
|
|
+ remarks: row.remarks,
|
|
|
+ value: row.value ? Number(row.value) : 0
|
|
|
+ };
|
|
|
+ this.dialogVisible = true;
|
|
|
+ },
|
|
|
+ async handleSave() {
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ classname: "sysmanage.develop.optiontype.optiontype",
|
|
|
+ method: "optiontypeupdate",
|
|
|
+ content: {
|
|
|
+ typename: "bathroomprepoints",
|
|
|
+ value: this.editForm.value,
|
|
|
+ remarks: this.editForm.remarks
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.tool.showMessage(res, () => {
|
|
|
+ this.dialogVisible = false;
|
|
|
+ this.fetchRuleData();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ async getWorkOrderTypeList() {
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ id: 2026051511261302,
|
|
|
+ content: {
|
|
|
+ pageNumber: 1,
|
|
|
+ pageSize: 100,
|
|
|
+ where: {
|
|
|
+ condition: ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (res && res.data) {
|
|
|
+ this.workOrderTypeList = res.data;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async fetchEditorData() {
|
|
|
+ if (this.isLoading) return;
|
|
|
+ this.isLoading = true;
|
|
|
+ try {
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ id: 2026052510103006,
|
|
|
+ content: {
|
|
|
+ rules: []
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (res && res.data && res.data.rules) {
|
|
|
+ this.editorData = res.data.rules.map((item) => ({
|
|
|
+ sc_workorder_templateid: item.sc_workorder_templateid,
|
|
|
+ a_symbol: item.a_symbol || "≥",
|
|
|
+ a_count: item.a_count || 0,
|
|
|
+ a_ratio: item.a_ratio || 0,
|
|
|
+ a_team: item.a_team || "",
|
|
|
+ c_symbol: item.c_symbol || "=",
|
|
|
+ c_count: item.c_count || 0,
|
|
|
+ c_ratio: item.c_ratio || 0,
|
|
|
+ c_team: item.c_team || "",
|
|
|
+ isNew: false
|
|
|
+ }));
|
|
|
+ } else {
|
|
|
+ this.editorData = [];
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error("fetchEditorData error:", e);
|
|
|
+ } finally {
|
|
|
+ this.isLoading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async fetchResultListData() {
|
|
|
+ try {
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ id: 2026052510102006,
|
|
|
+ content: {
|
|
|
+ pageSize: 20,
|
|
|
+ pageNumber: 1,
|
|
|
+ pageSorting: "t1.sc_workorder_templateid, t1.sc_points_rulesmxid"
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (res && res.data) {
|
|
|
+ this.resultListData = Array.isArray(res.data) ? res.data : [];
|
|
|
+ } else {
|
|
|
+ this.resultListData = [];
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error("fetchResultListData error:", e);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleAddRow() {
|
|
|
+ const newRow = {
|
|
|
+ sc_workorder_templateid: "",
|
|
|
+ a_symbol: "≥",
|
|
|
+ a_count: 1,
|
|
|
+ a_ratio: 100,
|
|
|
+ a_team: "",
|
|
|
+ c_symbol: "=",
|
|
|
+ c_count: 1,
|
|
|
+ c_ratio: 0,
|
|
|
+ c_team: "",
|
|
|
+ isNew: true
|
|
|
+ };
|
|
|
+ this.editorData.push(newRow);
|
|
|
+ },
|
|
|
+ handleWorkOrderTypeChange(index, row) {
|
|
|
+ const item = this.workOrderTypeList.find((w) => w.sc_workorder_templateid === row.sc_workorder_templateid);
|
|
|
+ if (item) {
|
|
|
+ this.editorData[index].workOrderTypeName = item.name;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async handleEditorSave(index) {
|
|
|
+ const row = this.editorData[index];
|
|
|
+ if (!row.sc_workorder_templateid) {
|
|
|
+ this.$message.warning("请选择工单模版");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!row.a_team) {
|
|
|
+ this.$message.warning("请选择A积分团队定位");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!row.c_team) {
|
|
|
+ this.$message.warning("请选择C积分团队定位");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!row.a_count && row.a_count !== 0) {
|
|
|
+ this.$message.warning("请填写A积分人数");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!row.c_count && row.c_count !== 0) {
|
|
|
+ this.$message.warning("请填写C积分人数");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!row.a_ratio && row.a_ratio !== 0) {
|
|
|
+ this.$message.warning("请填写A积分占比");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!row.c_ratio && row.c_ratio !== 0) {
|
|
|
+ this.$message.warning("请填写C积分占比");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const aRatio = Number(row.a_ratio) || 0;
|
|
|
+ const cRatio = Number(row.c_ratio) || 0;
|
|
|
+ if (aRatio + cRatio !== 100) {
|
|
|
+ this.$message.warning("A积分占比 + C积分占比必须等于100%");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ id: "ID2026052710100006",
|
|
|
+ content: {
|
|
|
+ sc_points_rulesmxid: row.sc_points_rulesmxid,
|
|
|
+ sc_workorder_templateid: row.sc_workorder_templateid,
|
|
|
+ a_symbol: row.a_symbol,
|
|
|
+ a_count: Number(row.a_count) || 0,
|
|
|
+ a_ratio: Number(row.a_ratio) || 0,
|
|
|
+ c_symbol: row.c_symbol,
|
|
|
+ c_count: Number(row.c_count) || 0,
|
|
|
+ c_ratio: Number(row.c_ratio) || 0
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (res && res.msg === "成功") {
|
|
|
+ this.$message.success("保存成功");
|
|
|
+ this.fetchResultListData();
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg || "保存失败");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async handleEditorDelete(index) {
|
|
|
+ const deleteId = this.editorData[index].sc_workorder_templateid;
|
|
|
+ const tempData = this.editorData.filter((_, i) => i !== index);
|
|
|
+ const validRows = tempData.filter((item) => item.sc_workorder_templateid);
|
|
|
+ const rules = validRows.map((item) => ({
|
|
|
+ sc_workorder_templateid: item.sc_workorder_templateid,
|
|
|
+ a_symbol: item.a_symbol,
|
|
|
+ a_count: item.a_count,
|
|
|
+ a_ratio: item.a_ratio,
|
|
|
+ c_symbol: item.c_symbol,
|
|
|
+ c_count: item.c_count,
|
|
|
+ c_ratio: item.c_ratio
|
|
|
+ }));
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ id: 2026052510103006,
|
|
|
+ content: {
|
|
|
+ rules: rules
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (res && res.msg === "成功") {
|
|
|
+ this.$message.success("删除成功");
|
|
|
+ this.editorData = tempData;
|
|
|
+ this.fetchResultListData();
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg || "删除失败");
|
|
|
+ }
|
|
|
+ },
|
|
|
+ objectSpanMethod({ row, column, rowIndex, columnIndex }) {
|
|
|
+ if (columnIndex === 1) {
|
|
|
+ const currentRow = this.mergedRuleData[rowIndex];
|
|
|
+ const prevRow = this.mergedRuleData[rowIndex - 1];
|
|
|
+ if (prevRow && prevRow.workOrderTypeName === currentRow.workOrderTypeName) {
|
|
|
+ return {
|
|
|
+ rowspan: 0,
|
|
|
+ colspan: 0
|
|
|
+ };
|
|
|
+ }
|
|
|
+ let rowspan = 1;
|
|
|
+ for (let i = rowIndex + 1; i < this.mergedRuleData.length; i++) {
|
|
|
+ if (this.mergedRuleData[i].workOrderTypeName === currentRow.workOrderTypeName) {
|
|
|
+ rowspan++;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ rowspan,
|
|
|
+ colspan: 1
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleResultEdit(row) {
|
|
|
+ const editRow = {
|
|
|
+ sc_points_rulesmxid: row.sc_points_rulesmxid,
|
|
|
+ sc_workorder_templateid: row.sc_workorder_templateid,
|
|
|
+ a_symbol: row.a_symbol || "≥",
|
|
|
+ a_count: row.a_count || 0,
|
|
|
+ a_ratio: row.a_ratio || 0,
|
|
|
+ a_team: row.a_team || "",
|
|
|
+ c_symbol: row.c_symbol || "=",
|
|
|
+ c_count: row.c_count || 0,
|
|
|
+ c_ratio: row.c_ratio || 0,
|
|
|
+ c_team: row.c_team || "",
|
|
|
+ isNew: false
|
|
|
+ };
|
|
|
+ this.editorData = [editRow];
|
|
|
+ this.$nextTick(() => {
|
|
|
+ const container = document.querySelector(".integration-rule-page");
|
|
|
+ if (container) {
|
|
|
+ container.scrollTo({
|
|
|
+ top: 300,
|
|
|
+ behavior: "smooth"
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ async handleResultDelete(row) {
|
|
|
+ try {
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ id: 2026052510104006,
|
|
|
+ content: {
|
|
|
+ sc_points_rulesmxid: row.sc_points_rulesmxid
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (res && res.msg === "成功") {
|
|
|
+ this.$message.success("删除成功");
|
|
|
+ this.fetchResultListData();
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.msg || "删除失败");
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error("handleResultDelete error:", e);
|
|
|
+ this.$message.error("删除失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
-<style></style>
|
|
|
+<style scoped>
|
|
|
+.integration-rule-page {
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+.section-box {
|
|
|
+ background: #fff;
|
|
|
+ padding: 20px;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+.section-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 16px;
|
|
|
+}
|
|
|
+.mt-16 {
|
|
|
+ margin-top: 16px;
|
|
|
+}
|
|
|
+.editor-footer {
|
|
|
+ margin-top: 16px;
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+</style>
|