|
|
@@ -0,0 +1,340 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <el-button size="small" style="width:120px" type="primary" @click="openDialog">{{ $t('设 置') }}</el-button>
|
|
|
+ <el-dialog :title="$t(`服务改善自动创建规则`)" append-to-body :visible.sync="dialogVisible" width="860px">
|
|
|
+ <div style="margin-bottom: 16px;">
|
|
|
+ <div style="display: flex; justify-content: space-between; align-items: center;">
|
|
|
+ <span style="font-weight: bold;">{{ $t('设置真因分析产品经理') }}</span>
|
|
|
+ <el-button type="primary" size="mini" @click="addRow">{{ $t('添加行') }}</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-table :data="tableData" style="width: 100%" border size="small">
|
|
|
+ <el-table-column :label="$t('产品经理')" prop="name">
|
|
|
+ <template slot-scope="scope" >
|
|
|
+ <el-popover
|
|
|
+ v-if="scope.row.timestamp"
|
|
|
+ placement="bottom-start"
|
|
|
+ width="600"
|
|
|
+ v-model="scope.row.popoverVisible"
|
|
|
+ trigger="click"
|
|
|
+ @show="resetParam"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="managerParam.content.where.condition"
|
|
|
+ :placeholder="$t('搜索')"
|
|
|
+ size="small"
|
|
|
+ class="mb-10"
|
|
|
+ @keyup.native.enter="searchManager"
|
|
|
+ @clear="searchManager"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
+ <i slot="suffix" class="el-input__icon el-icon-search" @click="searchManager"></i>
|
|
|
+ </el-input>
|
|
|
+ <tableTemplate
|
|
|
+ v-if="scope.row.popoverVisible"
|
|
|
+ ref="managerTable"
|
|
|
+ :layout="managerTableCols"
|
|
|
+ :param="managerParam"
|
|
|
+ :isInput="false"
|
|
|
+ :isPagination="true"
|
|
|
+ :height="'300px'"
|
|
|
+ size="mini"
|
|
|
+ @rowClick="(val) => handleManagerSelect(val, scope.row)"
|
|
|
+ />
|
|
|
+ <el-input
|
|
|
+ slot="reference"
|
|
|
+ v-model="scope.row.name"
|
|
|
+ :placeholder="$t('请选择')"
|
|
|
+ readonly
|
|
|
+ style="width: 100%"
|
|
|
+ size="mini"
|
|
|
+ />
|
|
|
+ </el-popover>
|
|
|
+ <span v-else>{{ scope.row.name }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('商品型号')">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-popover
|
|
|
+ v-if="scope.row.timestamp"
|
|
|
+ placement="bottom-start"
|
|
|
+ width="600"
|
|
|
+ v-model="scope.row.modelPopoverVisible"
|
|
|
+ trigger="click"
|
|
|
+ @show="resetModelParam(scope.row, scope.$index)"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="modelParam.content.where.condition"
|
|
|
+ :placeholder="$t('搜索')"
|
|
|
+ size="small"
|
|
|
+ class="mb-10"
|
|
|
+ @keyup.native.enter="searchModel(scope.row, scope.$index)"
|
|
|
+ @clear="searchModel(scope.row, scope.$index)"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
+ <i slot="suffix" class="el-input__icon el-icon-search" @click="searchModel(scope.row, scope.$index)"></i>
|
|
|
+ </el-input>
|
|
|
+ <tableTemplate
|
|
|
+ v-if="scope.row.modelPopoverVisible"
|
|
|
+ ref="modelTable"
|
|
|
+ :layout="modelTableCols"
|
|
|
+ :param="modelParam"
|
|
|
+ :isInput="false"
|
|
|
+ :isPagination="true"
|
|
|
+ :height="'300px'"
|
|
|
+ size="mini"
|
|
|
+ :checkbox="true"
|
|
|
+ :rowKey="getModelValue"
|
|
|
+ :reserveSelection="true"
|
|
|
+ @selectionChange="(val) => handleModelSelectionChange(val, scope.row)"
|
|
|
+ @listData="(val) => syncModelSelection(val, scope.row, scope.$index)"
|
|
|
+ />
|
|
|
+ <el-input
|
|
|
+ slot="reference"
|
|
|
+ :value="formatModelLabel(scope.row.productModel)"
|
|
|
+ :placeholder="$t('请选择')"
|
|
|
+ readonly
|
|
|
+ @click.native="modelParam.content.hrid = scope.row.hrid"
|
|
|
+ style="width: 100%"
|
|
|
+ size="mini"
|
|
|
+ />
|
|
|
+ </el-popover>
|
|
|
+ <span v-else>{{ formatModelLabel(scope.row.productModel) || $t('未选择') }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column :label="$t('操作')" width="100" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button type="text" size="mini" @click="deleteRow(scope.row, scope.$index)">{{ $t('删除') }}</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <div class="dialog-footer" style="margin-top: 20px; text-align: right;">
|
|
|
+ <el-button size="small" @click="dialogVisible = false" class="normal-btn-width">{{$t('取 消')}}</el-button>
|
|
|
+ <el-button size="small" type="primary" class="normal-btn-width" @click="onSubmit">{{$t('确 定')}}</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import tableTemplate from '@/template/popoverTable/table'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "serviceImprovementRule",
|
|
|
+ components: { tableTemplate },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ dialogVisible: false,
|
|
|
+ tableData: [],
|
|
|
+ managerOptions: [], // 应该从接口获取
|
|
|
+ managerTableCols: [
|
|
|
+ { columnname: 'name', title: this.$t('姓名') },
|
|
|
+ { columnname: 'depname', title: this.$t('部门') },
|
|
|
+ { columnname: 'position', title: this.$t('职位') },
|
|
|
+ { columnname: 'depname', title: this.$t('负责区域') },
|
|
|
+ { columnname: 'phonenumber', title: this.$t('手机号码') }
|
|
|
+ ],
|
|
|
+ modelTableCols: [
|
|
|
+ { columnname: 'model', title: this.$t('型号') }
|
|
|
+ ],
|
|
|
+ managerParam: {
|
|
|
+ "content": {
|
|
|
+ "where": {
|
|
|
+ "condition": ""
|
|
|
+ },
|
|
|
+ "pageNumber": 1,
|
|
|
+ "pageSize": 20
|
|
|
+ },
|
|
|
+ "id": 2026011711061202,
|
|
|
+ },
|
|
|
+ modelParam: {
|
|
|
+ "content": {
|
|
|
+ "where": {
|
|
|
+ "condition": ""
|
|
|
+ },
|
|
|
+ "pageNumber": 1,
|
|
|
+ "pageSize": 20
|
|
|
+ },
|
|
|
+ "id": 2026011710020402,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ openDialog() {
|
|
|
+ this.dialogVisible = true;
|
|
|
+ this.queryData();
|
|
|
+ },
|
|
|
+ addRow() {
|
|
|
+ this.tableData.push({
|
|
|
+ timestamp: new Date().getTime(),
|
|
|
+ name: '',
|
|
|
+ hrid: '',
|
|
|
+ userid: '',
|
|
|
+ productModel: [],
|
|
|
+ popoverVisible: false,
|
|
|
+ modelPopoverVisible: false
|
|
|
+ });
|
|
|
+ },
|
|
|
+ async deleteRow(row,index) {
|
|
|
+ console.log(row,index)
|
|
|
+ if (row.timestamp) {
|
|
|
+ this.tableData.splice(index, 1)
|
|
|
+ } else {
|
|
|
+ this.$confirm(this.$t('确认删除吗?'), this.$t('提示'), {
|
|
|
+ confirmButtonText: this.$t('确定'),
|
|
|
+ cancelButtonText: this.$t('取消'),
|
|
|
+ type: 'warning'
|
|
|
+ }).then(async () => {
|
|
|
+ await this.$api.requested({
|
|
|
+ "content": {
|
|
|
+ "hrid": row.hrid
|
|
|
+ },
|
|
|
+ "id": 2026011710014002,
|
|
|
+ });
|
|
|
+ this.tableData.splice(index, 1);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ resetParam() {
|
|
|
+ this.managerParam.content.where.condition = '';
|
|
|
+ this.managerParam.content.pageNumber = 1;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.$refs.managerTable) {
|
|
|
+ const tables = Array.isArray(this.$refs.managerTable) ? this.$refs.managerTable : [this.$refs.managerTable];
|
|
|
+ tables.forEach(table => table.listData());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ searchManager() {
|
|
|
+ this.managerParam.content.pageNumber = 1;
|
|
|
+ if (this.$refs.managerTable) {
|
|
|
+ const tables = Array.isArray(this.$refs.managerTable) ? this.$refs.managerTable : [this.$refs.managerTable];
|
|
|
+ tables.forEach(table => table.listData());
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleManagerSelect(val, row) {
|
|
|
+ this.$set(row, 'name', val.name);
|
|
|
+ this.$set(row, 'hrid', val.hrid);
|
|
|
+ this.$set(row, 'userid', val.userid);
|
|
|
+ if (!row.timestamp) {
|
|
|
+ this.$set(row, 'timestamp', new Date().getTime());
|
|
|
+ }
|
|
|
+ row.popoverVisible = false;
|
|
|
+ },
|
|
|
+ resetModelParam(row, index) {
|
|
|
+ this.modelParam.content.where.condition = '';
|
|
|
+ this.modelParam.content.pageNumber = 1;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ const table = this.getTableRef(this.$refs.modelTable, index);
|
|
|
+ if (table) {
|
|
|
+ table.listData();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ searchModel(row, index) {
|
|
|
+ this.modelParam.content.pageNumber = 1;
|
|
|
+ const table = this.getTableRef(this.$refs.modelTable, index);
|
|
|
+ if (table) {
|
|
|
+ table.listData();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleModelSelectionChange(val, row) {
|
|
|
+ const models = (val || []).map(item => this.getModelValue(item)).filter(Boolean);
|
|
|
+ const uniqueModels = models.filter((item, idx) => models.indexOf(item) === idx);
|
|
|
+ this.$set(row, 'productModel', uniqueModels);
|
|
|
+ },
|
|
|
+ syncModelSelection(list, row, index) {
|
|
|
+ const table = this.getTableRef(this.$refs.modelTable, index);
|
|
|
+ if (!table || !table.$refs || !table.$refs.table) return;
|
|
|
+ const selectedKeys = Array.isArray(row.productModel) ? row.productModel : (row.productModel ? [row.productModel] : []);
|
|
|
+ (list || []).forEach(item => {
|
|
|
+ const key = this.getModelValue(item);
|
|
|
+ const shouldBeSelected = selectedKeys.includes(key);
|
|
|
+ table.$refs.table.toggleRowSelection(item, shouldBeSelected);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getTableRef(refs, index) {
|
|
|
+ if (Array.isArray(refs)) {
|
|
|
+ return refs[index];
|
|
|
+ }
|
|
|
+ return refs;
|
|
|
+ },
|
|
|
+ getModelValue(item) {
|
|
|
+ return item.model || item.value || item.label || item.itemno;
|
|
|
+ },
|
|
|
+ formatModelLabel(models) {
|
|
|
+ const list = Array.isArray(models) ? models : (models ? [models] : []);
|
|
|
+ return list.join('、');
|
|
|
+ },
|
|
|
+ async queryData() {
|
|
|
+ // TODO: 调用接口获取当前配置
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ "content": {
|
|
|
+ "where": {
|
|
|
+ "condition": ""
|
|
|
+ },
|
|
|
+ "pageNumber": 1,
|
|
|
+ "pageSize": 20
|
|
|
+ },
|
|
|
+ "id": 2026011709524202,
|
|
|
+ });
|
|
|
+ if (res.code === 1) {
|
|
|
+ this.tableData = (res.data || []).map(item => ({
|
|
|
+ ...item,
|
|
|
+ name: item.name, // 确保有 name 字段
|
|
|
+ productModel: Array.isArray(item.models) ? item.models : (item.models ? item.models.split(',') : []), // 确保 productModel 是数组
|
|
|
+ popoverVisible: false,
|
|
|
+ modelPopoverVisible: false
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async onSubmit() {
|
|
|
+ // TODO: 调用接口保存配置
|
|
|
+ const updateRows = this.tableData.filter(item => item.timestamp);
|
|
|
+ if (updateRows.length === 0) {
|
|
|
+ this.$message.warning(this.$t('没有可保存的数据'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let successCount = 0;
|
|
|
+ let failCount = 0;
|
|
|
+
|
|
|
+ for (const item of updateRows) {
|
|
|
+ const res = await this.$api.requested({
|
|
|
+ "content": {
|
|
|
+ "hrid": item.hrid,
|
|
|
+ "userid": item.userid,
|
|
|
+ "models": item.productModel,
|
|
|
+ },
|
|
|
+ "id": 2026011709520902,
|
|
|
+ });
|
|
|
+
|
|
|
+ if (res.code === 1) {
|
|
|
+ successCount++;
|
|
|
+ } else {
|
|
|
+ failCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (failCount === 0) {
|
|
|
+ this.$message.success(this.$t('保存成功'));
|
|
|
+ this.dialogVisible = false;
|
|
|
+ this.$emit('queryRule');
|
|
|
+ } else {
|
|
|
+ this.$message.warning(this.$t('保存完成,成功 {0} 条,失败 {1} 条', [successCount, failCount]));
|
|
|
+ // 失败时不关闭,或者刷新列表?这里选择刷新
|
|
|
+ this.$emit('queryRule');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.dialog-footer {
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+</style>
|