|
|
@@ -326,6 +326,13 @@
|
|
|
v-hasPermi="['qw:sop:remove']"
|
|
|
>删除
|
|
|
</el-button>
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="text"
|
|
|
+ @click="handleSkipSop(scope.row,1)"
|
|
|
+ v-hasPermi="['qw:sop:edit']"
|
|
|
+ >跳过sop
|
|
|
+ </el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
@@ -469,6 +476,67 @@
|
|
|
<qwUserList ref="QwUserList" @selectUserList="selectUserList"></qwUserList>
|
|
|
</el-dialog>
|
|
|
|
|
|
+ <el-dialog
|
|
|
+ :title="skipSopDialog.title"
|
|
|
+ :visible.sync="skipSopDialog.open"
|
|
|
+ width="600px"
|
|
|
+ append-to-body
|
|
|
+>
|
|
|
+ <el-form
|
|
|
+ ref="skipSopForm"
|
|
|
+ :model="skipSopForm"
|
|
|
+ :rules="skipSopRules"
|
|
|
+ label-width="80px"
|
|
|
+ >
|
|
|
+ <div v-for="(item, index) in skipSopForm.conditions" :key="index" class="condition-item" style="margin-bottom: 15px; padding: 10px; border: 1px solid #eee; border-radius: 4px;">
|
|
|
+ <el-form-item :label="`第几天`" :prop="`conditions[${index}].dayNum`">
|
|
|
+ <el-input
|
|
|
+ v-model.number="item.dayNum"
|
|
|
+ placeholder="输入天数(大于0)"
|
|
|
+ style="width: 120px;"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="`开始时间`" :prop="`conditions[${index}].startDate`">
|
|
|
+ <el-time-select
|
|
|
+ v-model="item.startDate"
|
|
|
+ placeholder="选择开始时间"
|
|
|
+ :picker-options="{ start: '00:00', step: '00:15', end: '23:45' }"
|
|
|
+ style="width: 120px;"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="`结束时间`" :prop="`conditions[${index}].endDate`">
|
|
|
+ <el-time-select
|
|
|
+ v-model="item.endDate"
|
|
|
+ placeholder="选择结束时间"
|
|
|
+ :picker-options="{ start: '00:00', step: '00:15', end: '23:45' }"
|
|
|
+ style="width: 120px;"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-delete"
|
|
|
+ style="color: #ff4949;"
|
|
|
+ @click="removeCondition(index)"
|
|
|
+ >删除</el-button>
|
|
|
+ </div>
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-plus"
|
|
|
+ style="color: #409eff;"
|
|
|
+ @click="addCondition"
|
|
|
+ v-if="skipSopForm.conditions.length < 10"
|
|
|
+ >添加条件</el-button>
|
|
|
+ <div style="color: #999; font-size: 12px; margin-top: 10px;">
|
|
|
+ <p>提示:</p>
|
|
|
+ <p>2. 时间可填/不填(不填表示跳过整天)</p>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="cancelSkipSop">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submitSkipSop">确认跳过</el-button>
|
|
|
+ </div>
|
|
|
+</el-dialog>
|
|
|
+
|
|
|
<!-- 单独的修改时间 -->
|
|
|
<el-dialog :title="outTimeOpen.title" :visible.sync="outTimeOpen.open" width="800px">
|
|
|
<el-card class="box-card">
|
|
|
@@ -900,7 +968,9 @@ import {
|
|
|
updateSop,
|
|
|
updateSopStatus,
|
|
|
updateStatus,
|
|
|
- videoList
|
|
|
+ videoList,
|
|
|
+ handleSkipSop,
|
|
|
+ getSop
|
|
|
} from '@/api/qw/sop'
|
|
|
import {sendMsgSop} from "@/api/qw/sopUserLogsInfo";
|
|
|
import {listSopTemp} from "@/api/qw/sopTemp";
|
|
|
@@ -919,6 +989,36 @@ export default {
|
|
|
components: {CustomerGroupDetails, qwUserList, ImageUpload, sopLogsDetails, SendMsgSopOpenTool},
|
|
|
data() {
|
|
|
return {
|
|
|
+
|
|
|
+ skipSopDialog: {
|
|
|
+ open: false,
|
|
|
+ title: "跳过SOP操作",
|
|
|
+ rowId: null, // 目标SOP的ID
|
|
|
+ },
|
|
|
+ // 跳过SOP表单
|
|
|
+ skipSopForm: {
|
|
|
+ conditions: [
|
|
|
+ {
|
|
|
+ dayNum: 1, // 第几天
|
|
|
+ startDate: "", // 开始时间
|
|
|
+ endDate: "", // 结束时间
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ // 跳过SOP表单验证规则
|
|
|
+ skipSopRules: {
|
|
|
+ dayNum: [
|
|
|
+ { required: true, message: "天数不能为空", trigger: "blur" },
|
|
|
+ { type: "number", min: 1, message: "天数必须大于0", trigger: "blur" },
|
|
|
+ ],
|
|
|
+ startDate: [
|
|
|
+ { pattern: /^([01]\d|2[0-3]):[0-5]\d$/, message: "时间格式为HH:mm", trigger: "blur" },
|
|
|
+ ],
|
|
|
+ endDate: [
|
|
|
+ { pattern: /^([01]\d|2[0-3]):[0-5]\d$/, message: "时间格式为HH:mm", trigger: "blur" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+
|
|
|
// 存储每一行的展开状态
|
|
|
expandedRows: {},
|
|
|
//模板查询
|
|
|
@@ -1111,7 +1211,151 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
+ handleSkipSop(row) {
|
|
|
+ const ids = row.id || this.ids;
|
|
|
+ // 获取原始数据详情
|
|
|
+
|
|
|
+ getSop(ids).then(response => {
|
|
|
+ // 解析skipSopJson字段中的数据
|
|
|
+ if (response.data && response.data.skipSopJson) {
|
|
|
+ try {
|
|
|
+ const skipData = JSON.parse(response.data.skipSopJson);
|
|
|
+ if (Array.isArray(skipData)) {
|
|
|
+ // 如果是数组格式,直接赋值
|
|
|
+ this.skipSopForm.conditions = skipData.length > 0 ? skipData : [
|
|
|
+ { dayNum: 1, startDate: "", endDate: "" }
|
|
|
+ ];
|
|
|
+ } else if (skipData.conditions && Array.isArray(skipData.conditions)) {
|
|
|
+ // 如果是对象格式且包含conditions数组
|
|
|
+ this.skipSopForm.conditions = skipData.conditions.length > 0 ? skipData.conditions : [
|
|
|
+ { dayNum: 1, startDate: "", endDate: "" }
|
|
|
+ ];
|
|
|
+ } else {
|
|
|
+ // 如果是其他格式,尝试直接使用skipData(假设它本身就是条件数组)
|
|
|
+ this.skipSopForm.conditions = Array.isArray(skipData) ? skipData : [
|
|
|
+ { dayNum: 1, startDate: "", endDate: "" }
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析skipSopJson失败', e);
|
|
|
+ // 如果解析失败,使用默认值
|
|
|
+ this.skipSopForm.conditions = [
|
|
|
+ { dayNum: 1, startDate: "", endDate: "" }
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果没有skipSopJson数据,使用默认值
|
|
|
+ this.skipSopForm.conditions = [
|
|
|
+ { dayNum: 1, startDate: "", endDate: "" }
|
|
|
+ ];
|
|
|
+ }
|
|
|
|
|
|
+ // 设置弹窗数据
|
|
|
+ this.skipSopDialog.rowId = ids;
|
|
|
+ this.skipSopDialog.open = true;
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('获取SOP详情失败', error);
|
|
|
+ // 出错时也打开弹窗,使用默认数据
|
|
|
+ this.skipSopForm.conditions = [
|
|
|
+ { dayNum: 1, startDate: "", endDate: "" }
|
|
|
+ ];
|
|
|
+ this.skipSopDialog.rowId = ids;
|
|
|
+ this.skipSopDialog.open = true;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 添加条件
|
|
|
+ addCondition() {
|
|
|
+ if (this.skipSopForm.conditions.length >= 10) {
|
|
|
+ this.$message.warning("最多只能添加10个条件");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.skipSopForm.conditions.push({
|
|
|
+ dayNum: this.skipSopForm.conditions.length + 1,
|
|
|
+ startDate: "",
|
|
|
+ endDate: "",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 删除条件
|
|
|
+ removeCondition(index) {
|
|
|
+ // if (this.skipSopForm.conditions.length <= 1) {
|
|
|
+ // this.$message.warning("至少需要保留一个条件");
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ this.skipSopForm.conditions.splice(index, 1);
|
|
|
+ this.validateDuplicateDays(); // 删后验证天数重复
|
|
|
+ },
|
|
|
+ // 验证天数是否重复
|
|
|
+ validateDuplicateDays() {
|
|
|
+ const days = this.skipSopForm.conditions.map((c) => c.dayNum);
|
|
|
+ const uniqueDays = [...new Set(days)];
|
|
|
+ if (days.length !== uniqueDays.length) {
|
|
|
+ // this.$message.warning("不能有重复的天数");
|
|
|
+ // return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ // 提交跳过SOP
|
|
|
+ submitSkipSop() {
|
|
|
+ this.$refs.skipSopForm.validate((valid) => {
|
|
|
+ if (!valid) return;
|
|
|
+
|
|
|
+ // 验证天数不重复
|
|
|
+ if (!this.validateDuplicateDays()) return;
|
|
|
+
|
|
|
+ // 验证时间逻辑
|
|
|
+ let timeValid = true;
|
|
|
+ this.skipSopForm.conditions.forEach((item, idx) => {
|
|
|
+ if (item.startDate && item.endDate) {
|
|
|
+ // 比较时间(HH:mm格式)
|
|
|
+ const start = item.startDate.replace(":", "");
|
|
|
+ const end = item.endDate.replace(":", "");
|
|
|
+ if (start >= end) {
|
|
|
+ this.$message.warning(`第${idx + 1}个条件:结束时间必须晚于开始时间`);
|
|
|
+ timeValid = false;
|
|
|
+ }
|
|
|
+ } else if ((item.startDate && !item.endDate) || (!item.startDate && item.endDate)) {
|
|
|
+ this.$message.warning(`第${idx + 1}个条件:开始/结束时间需同时填写或同时为空`);
|
|
|
+ timeValid = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (!timeValid) return;
|
|
|
+
|
|
|
+ // 构造请求参数(根据后端接口调整)
|
|
|
+ const params = {
|
|
|
+ sopId: this.skipSopDialog.rowId,
|
|
|
+ paramList: this.skipSopForm.conditions.map((item) => ({
|
|
|
+ dayNum: item.dayNum,
|
|
|
+ startDate: item.startDate || null,
|
|
|
+ endDate: item.endDate || null,
|
|
|
+ })),
|
|
|
+ };
|
|
|
+
|
|
|
+ // 调用后端接口(需替换为实际接口)
|
|
|
+ // 示例:apiSkipSop(params).then(...)
|
|
|
+ this.$confirm("确定要跳过这些SOP任务吗?", "确认", {
|
|
|
+ type: "warning",
|
|
|
+ }).then(() => {
|
|
|
+ // 这里替换为实际的接口请求 handleSkipSop
|
|
|
+ setTimeout(() => {
|
|
|
+ handleSkipSop(params).then(response => {
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('跳过SOP操作失败:', error);
|
|
|
+ this.$message.error('跳过SOP操作失败');
|
|
|
+ });
|
|
|
+ this.$message.success("跳过SOP操作成功");
|
|
|
+ this.skipSopDialog.open = false;
|
|
|
+ this.getList(); // 刷新列表
|
|
|
+ }, 500);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 取消跳过SOP
|
|
|
+ cancelSkipSop() {
|
|
|
+ this.skipSopDialog.open = false;
|
|
|
+ if (this.$refs.skipSopForm) {
|
|
|
+ this.$refs.skipSopForm.resetFields();
|
|
|
+ }
|
|
|
+ },
|
|
|
/**
|
|
|
* SOP任务营期一键群发
|
|
|
*/
|