list.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. <!-- 模板区域 -->
  2. <template>
  3. <div>
  4. <!-- 模板内容 -->
  5. <el-form ref="queryForm" :inline="true" :model="queryform" label-width="100px" class="top-search">
  6. <el-form-item label="SOP名称">
  7. <el-input v-model="queryform.sopName" placeholder="请输入"></el-input>
  8. </el-form-item>
  9. <el-form-item label="状态">
  10. <el-select v-model="queryform.sopStatus" placeholder="请选择,支持关键词搜索" clearable filterable>
  11. <el-option label="全部" value=" "></el-option>
  12. <el-option label="启用" value="1"></el-option>
  13. <el-option label="停用" value="2"></el-option>
  14. </el-select>
  15. </el-form-item>
  16. <el-form-item>
  17. <el-button type="primary" @click="findPage()">查询</el-button>
  18. <el-button @click="resetForm()">重置</el-button>
  19. </el-form-item>
  20. </el-form>
  21. <div class="g-card ">
  22. <div class="mid-action">
  23. <el-button class="ml10" type="primary" @click="sopAdd">
  24. 新建
  25. </el-button>
  26. </div>
  27. <templateTable ref="commonTable" :operationWidth="200" :SerialShow="false" :showOperation="true"
  28. :showBatchDelete="false" :data="Result" :columns="Columns" @findPage="findPage">
  29. <template slot="buttonSlot" slot-scope="{ row }">
  30. <el-button type="text" @click="sopEdit(row)">编辑</el-button>
  31. <el-button type="text" @click="viewCopy(row)">复制</el-button>
  32. <el-button type="text" @click="viewDel(row)">删除</el-button>
  33. <el-button type="text" @click="viewEditStatus(row)">{{ row.sopStatus == 2 ? '启用' : '停用' }}</el-button>
  34. </template>
  35. </templateTable>
  36. </div>
  37. <el-dialog :title='dialogtitle' :visible.sync="sopAddShow" width="30%">
  38. <div>
  39. <el-form ref="form" :rules="rules" :model="form" label-width="120px">
  40. <el-form-item label="SOP名称" prop="sopName">
  41. <el-input v-model="form.sopName" placeholder="请输入SOP名称"></el-input>
  42. </el-form-item>
  43. <el-form-item label="场景描述" prop="sopDesc">
  44. <el-input type="textarea" v-model="form.sopDesc" maxlength="200" show-word-limit
  45. placeholder="请输入关键词"></el-input>
  46. </el-form-item>
  47. <el-form-item label="触发类型" prop="executeType">
  48. <el-select v-model="form.executeType" placeholder="请选择" clearable filterable @change="executeTypeChange">
  49. <el-option label="行为触发" :value="2"></el-option>
  50. <el-option label="时间触发" :value="1"></el-option>
  51. </el-select>
  52. </el-form-item>
  53. <el-form-item label="行为类型编码" :prop="form.executeType == '2' ? 'behaviorId' : ''">
  54. <el-select v-model="form.behaviorId" placeholder="请选择" clearable filterable>
  55. <el-option :label="item.name" :value="item.id" v-for="(item, index) in behaviorTypeList"
  56. :key="index.id"></el-option>
  57. </el-select>
  58. </el-form-item>
  59. <el-form-item label="时间类型" prop="timeType" class=" ">
  60. <el-radio-group v-model="form.timeType">
  61. <el-radio :label="1">相对时间</el-radio>
  62. <el-radio :label="2">绝对时间</el-radio>
  63. </el-radio-group>
  64. <i @click="addDomain" class="el-icon-circle-plus"
  65. style="color: #07c160;font-size: 20px;margin-left: 20px"></i>
  66. </el-form-item>
  67. <el-form-item label="时间间隔" prop="relativeTime" v-if="form.timeType == 1">
  68. <el-time-select v-model="relativeTime" :picker-options="{
  69. start: '00:00',
  70. step: '00:15',
  71. }" placeholder="选择时间">
  72. </el-time-select>
  73. </el-form-item>
  74. <el-form-item v-if="form.timeType == 2" v-for="domain in form.domains" :label="'选择日期'" :key="domain.key"
  75. prop="absoluteTime">
  76. <div class="flex a-c ">
  77. <el-date-picker v-model="domain.absoluteTime" type="date" placeholder="选择日期" value-format="yyyy-MM-dd"
  78. style="width: 70%;">
  79. </el-date-picker>
  80. <el-button @click.prevent="removeDomain(domain)" style="margin-left: 20px;">删除</el-button>
  81. </div>
  82. </el-form-item>
  83. <el-form-item label="关联标签" prop="tagGroupId">
  84. <el-select v-model="form.tagGroupId" placeholder="请选择" clearable filterable @change="tagsArrayChange">
  85. <el-option v-for="(item, index) in tagsArray" :key="index" :label="item.groupName"
  86. :value="item.id"></el-option>
  87. </el-select>
  88. </el-form-item>
  89. <el-form-item label="关联标签" prop="tagId" v-if="form.tagGroupId">
  90. <el-select v-model="form.tagIdlist" placeholder="请选择" clearable multiple>
  91. <el-option :label="item.name" :value="item.id" v-for="(item, index) in tagsSubSet"
  92. :key="index"></el-option>
  93. </el-select>
  94. </el-form-item>
  95. <el-form-item label="关联素材" prop="materialId">
  96. <el-select v-model="form.materialId" placeholder="请选择素材" clearable filterable>
  97. <el-option :label="item.materialName" :value="item.id" v-for="(item, index) in aterialList"
  98. :key="index"></el-option>
  99. </el-select>
  100. </el-form-item>
  101. </el-form>
  102. </div>
  103. <span slot="footer" class="dialog-footer">
  104. <el-button @click="sopAddShow = false">取 消</el-button>
  105. <el-button type="primary" @click="userOperation">确 定</el-button>
  106. </span>
  107. </el-dialog>
  108. </div>
  109. </template>
  110. <!-- 行为区域 -->
  111. <script>
  112. import templateTable from "@/components/templateTable.vue";
  113. import * as userActionTypeApi from '@/api/customerManage/userActionTypeConfig'//获取行为类型数据
  114. import * as api from '@/api/sop/customerOperationsSop'
  115. export default {
  116. components: {
  117. templateTable
  118. },
  119. // 数据存放区域
  120. data() {
  121. return {
  122. dialogtitle: "新建SOP规则",
  123. dialogtype: "add",
  124. relativeTime: "",
  125. aterialList: [],//素材列表
  126. tagsArray: [],//标签组列表
  127. tagsSubSet: [],//标签列表
  128. behaviorTypeList: [],
  129. sopAddShow: false,//转出弹窗
  130. queryform: {
  131. sopName: "",
  132. sopStatus: "",
  133. pageNum: 1,
  134. pageSize: 20,
  135. },//页面检索对象
  136. form: {
  137. id: "",
  138. sopName: "",//名称
  139. sopDesc: "",//场景描述
  140. executeType: "",//触发类型
  141. behaviorId: "",//类型编码
  142. timeType: 1,//时间类型
  143. relativeTime: "",// 时间间隔
  144. absoluteTime: "",//日期
  145. tagGroupId: "",//标签组id
  146. tagIdlist: [],//标签id数组
  147. tagId: "",//标签id字符串
  148. materialId: "",//素材id
  149. domains: [{
  150. absoluteTime: ''
  151. }],
  152. },//提交表单
  153. rules: {
  154. sopName: [
  155. {
  156. required: true,
  157. message: '请输入名称',
  158. trigger: 'blur',
  159. },
  160. ],
  161. sopDesc: [
  162. {
  163. required: true,
  164. message: '请输入描述',
  165. trigger: 'blur',
  166. },
  167. ],
  168. executeType: [
  169. {
  170. required: true,
  171. message: '请选择触发类型',
  172. trigger: 'chnage',
  173. },
  174. ],
  175. behaviorId: [
  176. {
  177. required: true,
  178. message: '请选择行为类型编码',
  179. trigger: 'chnage',
  180. },
  181. ],
  182. timeType: [
  183. {
  184. required: true,
  185. message: '请选择时间类型',
  186. trigger: 'chnage',
  187. },
  188. ],
  189. relativeTime: [
  190. {
  191. required: true,
  192. message: '请选择时间',
  193. trigger: 'chnage',
  194. },
  195. ],
  196. absoluteTime: [
  197. {
  198. required: true,
  199. message: '请选择时间',
  200. trigger: 'chnage',
  201. },
  202. ],
  203. tagGroupId: [
  204. {
  205. required: true,
  206. message: '请选择标签',
  207. trigger: 'chnage',
  208. },
  209. ],
  210. materialId: [
  211. {
  212. required: true,
  213. message: '请选择素材',
  214. trigger: 'chnage',
  215. },
  216. ],
  217. },
  218. Result: {
  219. },
  220. Columns: [
  221. { prop: "id", label: "SOPID", minWidth: 180, },
  222. { prop: "sopName", label: "SOP名称", minWidth: 180, },
  223. { prop: "sopDesc", label: "场景描述", minWidth: 180 },
  224. { prop: "executeType", label: "触发类型", minWidth: 180, formatter: this.executeTypeFormatter },
  225. { prop: "tagName", label: "关联标签", minWidth: 180 },
  226. { prop: "sopStatus", label: "启用状态", minWidth: 180, formatter: this.sopStatusFormatter },
  227. { prop: "createTime", label: "创建时间", minWidth: 180 },
  228. ],
  229. }
  230. },
  231. // 生命周期函数
  232. created() {
  233. this.userActionType();//获取行为类型
  234. this.fetchTags();
  235. this.materialListNew();
  236. },
  237. // 方法函数
  238. methods: {
  239. //多日期添加
  240. addDomain() {
  241. this.form.domains.push({
  242. absoluteTime: '',
  243. key: Date.now()
  244. });
  245. },
  246. //多个日期删除
  247. removeDomain(item) {
  248. var index = this.form.domains.indexOf(item)
  249. if (index !== -1) {
  250. this.form.domains.splice(index, 1)
  251. }
  252. },
  253. //编辑
  254. sopEdit(row) {
  255. this.dialogtype = 'edit';
  256. this.dialogtitle = '编辑SOP规则';
  257. api.getSop(row.id).then((res) => {
  258. if (res.code == 200) {
  259. res.data.tagIdlist = res.data.data.tagId.split(',')
  260. this.form.domains=res.data.data.absoluteTimeList;
  261. this.relativeTime = this.secondsToTimeFormat(res.data.data.relativeTime)
  262. Object.keys(this.form).forEach(key => {
  263. if (res.data.data.hasOwnProperty(key)) {
  264. this.form[key] = res.data.data[key];
  265. }
  266. });
  267. this.tagsSubSet = this.tagsArray.find(val => val.id == res.data.data.tagGroupId).weTags;//获取对应标签组标签列表
  268. this.sopAddShow = true;
  269. }
  270. })
  271. },
  272. //删除
  273. viewDel(row) {
  274. api.deleteSop(row.id).then((res) => {
  275. if (res.code == 200) {
  276. this.findPage();
  277. this.$message({
  278. type: 'success',
  279. message: '删除成功!'
  280. });
  281. } else {
  282. this.$message({
  283. type: 'error',
  284. message: res.msg,
  285. });
  286. }
  287. })
  288. },
  289. //复制数据
  290. viewCopy(row) {
  291. api.copySop(row.id).then((res) => {
  292. if (res.code == 200) {
  293. this.findPage();
  294. this.$message({
  295. type: 'success',
  296. message: '复制成功!'
  297. });
  298. } else {
  299. this.$message({
  300. type: 'error',
  301. message: res.msg,
  302. });
  303. }
  304. })
  305. },
  306. executeTypeFormatter(row) {
  307. return row.executeType == 1 ? '时间触发' : '行为触发'
  308. },
  309. sopStatusFormatter(row) {
  310. let sopStatus = row.sopStatus;
  311. return sopStatus == 2 ? '停用' : '启用'
  312. },
  313. executeTypeChange() {
  314. this.form.behaviorId = "";
  315. },
  316. //获取素材
  317. materialListNew() {
  318. api.materialListNew().then((res) => {
  319. this.aterialList = res;
  320. })
  321. },
  322. //获取对应标签组标签列表
  323. tagsArrayChange(value) {
  324. this.form.tagIdlist = [];//清空历史
  325. this.tagsSubSet = this.tagsArray.find(val => val.id == value).weTags;
  326. },
  327. //获取标签组
  328. fetchTags() {
  329. api.tagList({
  330. pageNum: 1,
  331. pageSize: 100,
  332. groupName: '',
  333. groupTagType: 1,
  334. }).then((res) => {
  335. if (res.code == 200) {
  336. this.tagsArray = res.rows;
  337. }
  338. })
  339. },
  340. userActionType() {
  341. userActionTypeApi.behaviorList({
  342. name: "",
  343. delFlag: 0,
  344. pageNum: 1,
  345. pageSize: 10,
  346. }).then((res) => {
  347. if (res.code == 200) {
  348. this.behaviorTypeList = res.rows;
  349. }
  350. })
  351. },
  352. // 启用/停用
  353. viewEditStatus(row) {
  354. api.disableStatus(row.id).then((res) => {
  355. if (res.code == 200) {
  356. this.findPage();
  357. this.$message({
  358. type: 'success',
  359. message: '操作成功!'
  360. });
  361. } else {
  362. this.$message({
  363. type: 'error',
  364. message: res.msg,
  365. });
  366. }
  367. })
  368. },
  369. // 操作用户
  370. userOperation() {
  371. this.form.relativeTime = this.form.relativeTime ? this.convertTimeToSeconds(this.relativeTime) : '';
  372. let list = [];
  373. this.form.domains.map(val => {
  374. list.push(val.absoluteTime)
  375. return
  376. })
  377. this.form.absoluteTime = list;
  378. this.$refs['form'].validate((valid) => {
  379. if (valid) {
  380. this.form.tagId = this.form.tagIdlist.join(',');
  381. if (this.dialogtype == 'add') {
  382. api.addSop(this.form).then((res) => {
  383. if (res.code == 200) {
  384. this.sopAddShow = false;
  385. this.findPage();
  386. this.$message({
  387. type: 'success',
  388. message: '添加成功!'
  389. });
  390. }
  391. })
  392. } else {
  393. api.updateSop(this.form).then((res) => {
  394. if (res.code == 200) {
  395. this.sopAddShow = false;
  396. this.findPage();
  397. this.$message({
  398. type: 'success',
  399. message: '编辑成功!'
  400. });
  401. }
  402. })
  403. }
  404. }
  405. })
  406. },
  407. /**
  408. * 停用
  409. * @param row status 状态 true 已绑定 false 未绑定
  410. */
  411. disableAction(row) {
  412. }, //列表查询
  413. findPage(data) {
  414. if (data && data.pageRequest) {
  415. this.queryform.pageNum = data.pageRequest.pageNum;
  416. this.queryform.pageSize = data.pageRequest.pageSize;
  417. }
  418. api.listSop(this.queryform).then((res) => {
  419. if (res.code == 200) {
  420. this.Result = res;
  421. }
  422. })
  423. },
  424. // 同步用户
  425. sopAdd() {
  426. this.sopAddShow = true;
  427. this.dialogtype = 'add';
  428. this.dialogtitle = '新建SOP规则';
  429. this.form = {
  430. id: "",
  431. sopName: "",//名称
  432. sopDesc: "",//场景描述
  433. executeType: "",//触发类型
  434. behaviorId: "",//类型编码
  435. timeType: 1,//时间类型
  436. relativeTime: "",// 时间间隔
  437. absoluteTime: "",//日期
  438. tagGroupId: "",//标签组id
  439. tagIdlist: [],//标签id数组
  440. tagId: "",//标签id字符串
  441. materialId: "",//素材id
  442. domains: [{
  443. value: ''
  444. }],
  445. }
  446. this.relativeTime = "";
  447. },
  448. resetForm() {
  449. this.queryform = {
  450. sopName: "",
  451. sopStatus: "",
  452. pageNum: 1,
  453. pageSize: 20,
  454. }
  455. },
  456. // 时间转换成秒
  457. convertTimeToSeconds(timeString) {
  458. const [hours, minutes] = timeString.split(':').map(Number);//分解为时 和 分
  459. // 计算总秒数
  460. const totalSeconds = (hours * 3600) + (minutes * 60);
  461. return totalSeconds;
  462. },
  463. //时分转换秒
  464. secondsToTimeFormat(seconds) {
  465. const hours = Math.floor(seconds / 3600); // 计算小时
  466. const minutes = Math.floor((seconds % 3600) / 60); // 计算分钟
  467. let timeString = '';
  468. if (hours > 0 && hours < 10) {
  469. timeString += `0${hours}:`;
  470. } else if (hours > 10) {
  471. timeString += `${hours}:`;
  472. } else {
  473. timeString += '00:'
  474. }
  475. if (minutes > 0 || hours > 0) {
  476. if (minutes < 10) {
  477. timeString += `0${minutes}`;
  478. } else {
  479. timeString += `${minutes}`;
  480. }
  481. }
  482. return timeString;
  483. }
  484. },
  485. // 计算属性
  486. computed: {
  487. }
  488. }
  489. </script>
  490. <!-- 样式区域 -->
  491. <style lang='scss' scoped></style>