zhangqi пре 3 месеци
родитељ
комит
559756dad5

+ 3 - 0
src/HDrpManagement/workBillModule/index.vue

@@ -25,6 +25,9 @@
             size="small"
           ></el-switch>
         </div>
+        <div v-else-if="scope.data.column.columnname == 'is_auto_transfer_template'">
+          {{ scope.data.column.data.is_auto_transfer_template ? $t("是") : $t("否") }}
+        </div>
         <div v-else>
           {{
             scope.data.column.data[[scope.data.column.columnname]]

+ 26 - 0
src/HDrpManagement/workBillModule/modules/detail.vue

@@ -39,6 +39,28 @@
           @onSuccess="queryMainData() && tool.checkAuth($route.name, 'close')"
           v-else
         />
+        <customBtn
+          btnName="设为自动转单模板"
+          message="确定设为自动转单模板吗?"
+          idName="2026011911011802"
+          keyName="sa_workorder_templateid"
+          :id="$route.query.id"
+          :paramData="[{ key: 'is_auto_transfer_template', value: true }]"
+          class="inline-16"
+          @onSuccess="queryMainData()"
+          v-if="!mainData.is_auto_transfer_template"
+        />
+        <!-- <customBtn
+          btnName="取消自动转单模板"
+          message="确定取消自动转单模板吗?"
+          idName="2026011911011802"
+          keyName="sa_workorder_templateid"
+          :id="$route.query.id"
+          :paramData="[{ key: 'is_auto_transfer_template', value: false }]"
+          class="inline-16"
+          @onSuccess="queryMainData()"
+          v-if="mainData.is_auto_transfer_template"
+        /> -->
       </div>
       <div slot="slot0">
         <taskDetail v-if="mainData.actiontype == '工序模板'"> </taskDetail>
@@ -100,6 +122,10 @@ export default {
           label: "是否启用",
           value: this.mainData.isused ? this.$t("是") : this.$t("否"),
         },
+        {
+          label: "是否自动转单模板",
+          value: this.mainData.is_auto_transfer_template ? this.$t("是") : this.$t("否"),
+        },
         {
           label: "操作类型",
           value:

Разлика између датотеке није приказан због своје велике величине
+ 3 - 0
src/HManagement/siteManage/securityConfig/index.vue


+ 340 - 0
src/HManagement/siteManage/securityConfig/modules/serviceImprovementRule.vue

@@ -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>

+ 158 - 0
src/HManagement/siteManage/securityConfig/modules/workOrderAutoCreateRule.vue

@@ -0,0 +1,158 @@
+<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>
+        </div>
+      </div>
+      
+      <el-table :data="tableData" style="width: 100%" border size="small">
+        <el-table-column :label="$t('商品供应方')" prop="supplier">
+          <template slot-scope="scope">
+            <span>{{ scope.row.supplier || $t('未知供应方') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column :label="$t('工单负责人')">
+          <template slot-scope="scope">
+            <el-select
+              v-model="scope.row.hrid"
+              filterable
+              remote
+              reserve-keyword
+              :placeholder="$t('请输入姓名搜索')"
+              :remote-method="searchPersonnel"
+              :loading="loading"
+              size="mini"
+              style="width: 100%"
+              @change="(val) => handlePersonnelChange(val, scope.row)"
+              @focus="searchPersonnel('')"
+            >
+              <el-option
+                v-for="item in personnelList"
+                :key="item.hrid"
+                :label="item.name"
+                :value="item.hrid">
+                <span style="float: left">{{ item.name }}</span>
+                <span style="float: right; color: #8492a6; font-size: 12px">{{ item.depname }}</span>
+              </el-option>
+            </el-select>
+          </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>
+export default {
+  name: "workOrderAutoCreateRule",
+  data() {
+    return {
+      dialogVisible: false,
+      tableData: [],
+      personnelList: [],
+      loading: false,
+      personnelParam: {
+        "content": {
+          "where": {
+            "condition": ""
+          },
+          "pageNumber": 1,
+          "pageSize": 50
+        },
+        "id": 20230213143003, // 使用与服务改善规则相同的人员搜索接口
+      }
+    }
+  },
+  methods: {
+    openDialog() {
+      this.dialogVisible = true;
+      this.queryData();
+      this.searchPersonnel('');
+    },
+    async searchPersonnel(query) {
+      this.loading = true;
+      this.personnelParam.content.where.condition = query;
+      try {
+        const res = await this.$api.requested(this.personnelParam);
+        if (res.code === 1) {
+          this.personnelList = res.data || [];
+        }
+      } finally {
+        this.loading = false;
+      }
+    },
+    handlePersonnelChange(val, row) {
+      const selected = this.personnelList.find(item => item.hrid === val);
+      if (selected) {
+        this.$set(row, 'name', selected.name);
+        this.$set(row, 'userid', selected.userid);
+      }
+    },
+    async queryData() {
+      // TODO: 调用接口获取当前配置及所有供应方
+      // 假设接口返回所有供应方列表,如果已配置则包含负责人信息
+      // 使用占位 ID,实际开发需替换
+      const res = await this.$api.requested({
+        "content": {
+        },
+        "id": 2026011914554702, // TODO: 替换为正确的查询接口ID
+      });
+      if (res.code === 1) {
+        this.tableData = res.data
+      } else {
+      }
+    },
+    async onSubmit() {
+      // 过滤出已设置负责人的行
+      const updateRows = this.tableData.filter(item => item.hrid);
+      
+      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": {
+            "sa_supplier_hrid": item.sa_supplier_hrid,
+            "hrid": item.hrid
+          },
+          "id": 2026011915463502,
+        });
+        
+        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>

+ 3 - 3
src/template/popoverTable/table.vue

@@ -3,10 +3,10 @@
     <el-input v-if="isInput !== false" style="width:200px;" :placeholder="$t('搜索')" :suffix-icon="param.content.where.condition?param.content.where.condition.length > 0?'':'':'el-icon-search'" v-model="param.content.where.condition" @keyup.native.enter="listData(param.content.pageNumber = 1)" @clear="listData(param.content.pageNumber = 1)" size="small" class="input-with-select inline-16 layout_search__panel" clearable>
     </el-input>
     <el-table ref="table" :fit="tool.calculatedColumnWidth($refs.table,layout)" :row-class-name="tableClassName" highlight-current-row :data="list"  size="mini" :height="height ? height : list.length <= 5?'280px':'calc(100vh - 268px)'"  @row-click="rowClick" style="width:100%;margin-top: 10px" :header-cell-style="{height:'40px',color:'#606266',fontWeight:'400',fontSize:'14px'}"
-              :cell-style="{height:'40px',color:'#666666',fontWeight:'400'}" border @selection-change="selectionChange">
+              :cell-style="{height:'40px',color:'#666666',fontWeight:'400'}" border @selection-change="selectionChange" :row-key="rowKey">
       <el-table-column
           type="selection"
-          width="35" fixed v-if="checkbox">
+          width="35" fixed v-if="checkbox" :reserve-selection="reserveSelection">
       </el-table-column>
       <el-table-column  ref="table" show-overflow-tooltip v-for="(col,index) in layout" :key="col.tablecolid" :prop="col.columnname" :label="col.title" :min-width="col.width || 150" :fixed="fixedName ? fixedName.indexOf(col.columnname)!= -1?redirect ? redirect : 'right' :false : false">
         <template v-slot:header="{ column,$index }" v-if="customHeader">
@@ -42,7 +42,7 @@
 <script>
 export default {
   name: "table",
-  props:['layout','custom','param','height','fixedName','width','checkbox','redirect','customHeader','prop','isInput','isPagination'],
+  props:['layout','custom','param','height','fixedName','width','checkbox','redirect','customHeader','prop','isInput','isPagination', 'rowKey', 'reserveSelection'],
   data () {
     return {
       list:[],

Неке датотеке нису приказане због велике количине промена