rule.vue 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  1. <template>
  2. <div class="all-box">
  3. <!-- 头部提示 -->
  4. <el-alert class="diy-tip" title="如何使用积分规则?" type="success" @close="tips_close" v-if="tips_show" description show-icon>
  5. <p>先【添加规则分类】,再【添加规则】</p>
  6. </el-alert>
  7. <div class="all">
  8. <div class="flex-box" v-loading="rule_loading">
  9. <div class="terr-left">
  10. <el-button size="medium" @click="add_class" type="primary">+ 添加规则分类</el-button>
  11. <div class="rule_class_box">
  12. <el-tree accordion :data="rule_tree" class="cate-tree" :props="defaultProps" :highlight-current="true" @node-click="handleNodeClick"></el-tree>
  13. </div>
  14. </div>
  15. <div class="terr-right border-right flex-1">
  16. <div class="flex-box flex-v-ce">
  17. <div class="name">{{ selectItem.name }}</div>
  18. <el-button size="medium" plain v-if="selectItem.id" @click="edit_class">编辑</el-button>
  19. </div>
  20. <div class="flex-box ruleSearch">
  21. <div class="flex-box btns flex-v-ce">
  22. <el-button size="small" @click="del_item" type="danger" plain>批量删除</el-button>
  23. <el-button size="small" @click="add_rule" type="primary">添加规则</el-button>
  24. <el-button size="small" type="success" @click="toleadShw = true" plain>导入规则</el-button>
  25. <el-button size="small" type="success" @click="derivedRule" plain>导出规则</el-button>
  26. </div>
  27. <div class="" style="display:inline-block; width:180px;margin:20px 0 0 10px;">
  28. <el-input
  29. placeholder="搜索规则内容"
  30. ref="search-bar"
  31. v-model="keyword"
  32. class="input-with-select"
  33. @keyup.enter.native="onFilterChanged"
  34. style=""
  35. >
  36. <el-button slot="append" icon="el-icon-search" @click="onFilterChanged"></el-button>
  37. </el-input>
  38. </div>
  39. </div>
  40. <el-table stripe ref="multipleTable" :data="item_list" tooltip-effect="dark" @selection-change="handleSelectionChange" @row-click="editDetails" align="center">
  41. <el-table-column type="selection" width="55"></el-table-column>
  42. <el-table-column prop="remark" label="内容" align="left"></el-table-column>
  43. <el-table-column label="分值" align="center">
  44. <template slot-scope="scope">
  45. <div v-if="scope.row.range_type == 1">
  46. <span :class="scope.row.min_point > 0 ? 'red' : 'green'">{{ scope.row.min_point }} {{ scope.row.pt_Obj.name }}</span>
  47. </div>
  48. <div v-if="scope.row.range_type == 2">
  49. <span :class="scope.row.min_point > 0 ? 'red' : 'green'">{{ scope.row.min_point }}</span>
  50. <span :class="scope.row.max_point > 0 ? 'red' : 'green'">{{ scope.row.max_point }} {{ scope.row.pt_Obj.name }}</span>
  51. </div>
  52. </template>
  53. </el-table-column>
  54. <el-table-column prop="remark" label="操作" align="center">
  55. <template slot-scope="scope">
  56. <span @click.stop="ruleQRcode(scope.row)" class="lookQrcode">查看二维码</span>
  57. <span class="blue" style="padding-left: 10px;cursor: pointer;">编辑</span>
  58. </template>
  59. </el-table-column>
  60. <template slot="empty">
  61. <noData></noData>
  62. </template>
  63. </el-table>
  64. </div>
  65. </div>
  66. </div>
  67. <el-dialog @close="closeCode" :visible.sync="innerVisible" width="444px" append-to-body>
  68. <div style="border-radius: 15px;border: 1px solid #f1f1f1;padding: 10px; width: 346px;box-sizing: border-box;margin: 0 auto;">
  69. <div id="qrcode" ref="qrcode"></div>
  70. </div>
  71. <div class="qrcodesave" ><span @click.stop="downloadE">下载保存此二维码</span></div>
  72. </el-dialog>
  73. <!-- 编辑添加分类 -->
  74. <el-dialog
  75. :title="class_type == 'add' ? '添加规则分类' : '编辑规则分类'"
  76. :visible.sync="class_show"
  77. @close="add_dept_close('dept_formdata')"
  78. :close-on-click-modal="false"
  79. width="500px"
  80. >
  81. <el-form :model="dept_formdata" ref="dept_formdata" :rules="dept_formdata_rules" label-width="80px">
  82. <el-form-item label="规则分类" prop="name"><el-input v-model="dept_formdata.name" maxlength="10" show-word-limit></el-input></el-form-item>
  83. <el-form-item label="上级分类">
  84. <el-cascader
  85. ref="dept"
  86. v-model="dept_formdata.pid"
  87. :options="rule_tree"
  88. :props="{ checkStrictly: true, label: 'name', value: 'id', children: 'child' }"
  89. clearable
  90. filterable
  91. ></el-cascader>
  92. </el-form-item>
  93. <div class="flex-box">
  94. <el-button type="danger" @click="del_dept" v-show="class_type == 'edit'">删除分类</el-button>
  95. <div class="flex-1"></div>
  96. <el-button @click="add_dept_close('dept_formdata')">取消</el-button>
  97. <el-button type="primary" @click="submit_add_dept('dept_formdata')" :loading="dept_loading" :disabled="dept_loading">确定</el-button>
  98. </div>
  99. </el-form>
  100. </el-dialog>
  101. <!-- 添加编辑规则 -->
  102. <el-dialog :title="rule_type == 'add' ? '添加规则' : '编辑规则'" :visible.sync="rule_show" :close-on-click-modal="false" width="600px">
  103. <el-form :model="rules_detail_form" ref="rules_detail_form" :rules="rules" label-width="80px">
  104. <el-form-item label="规则内容" prop="remark">
  105. <el-input v-model="rules_detail_form.remark" placeholder="请输入规则内容" type="textarea" :rows="5" maxlength="300" show-word-limit></el-input>
  106. </el-form-item>
  107. <el-form-item label="所属分类" prop="rule_id">
  108. <div style="position: relative;">
  109. <div
  110. style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 9;"
  111. @click="not_data"
  112. v-show="rule_tree !== null && rule_tree.length == 0"
  113. ></div>
  114. <el-cascader
  115. ref="dept2"
  116. placeholder="请选择分类"
  117. v-model="rules_detail_form.rule_id"
  118. :options="rule_tree"
  119. :props="{ checkStrictly: true, label: 'name', value: 'id', children: 'child' }"
  120. clearable
  121. filterable
  122. ></el-cascader>
  123. </div>
  124. </el-form-item>
  125. <el-form-item label="规则类型" prop="pt_id">
  126. <el-radio v-model="rules_detail_form.pt_id" :label="item.id" v-for="(item, index) in point_types" :key="index" v-show="item.name !== '绩效分'">
  127. {{ item.name }}
  128. </el-radio>
  129. </el-form-item>
  130. <el-form-item label="规则积分" prop="range_type">
  131. <el-radio-group v-model="rules_detail_form.range_type">
  132. <el-radio :label="item.value" v-for="(item, index) in range_type_arr" :key="index">{{ item.name }}</el-radio>
  133. </el-radio-group>
  134. </el-form-item>
  135. <div class="flex-box flex-v-ce">
  136. <el-form-item class="select_width">
  137. <el-input placeholder="请输入分值" v-model.number="rules_detail_form.min_point" type="age" class="input-with-select">
  138. <el-select v-model="integral_select_name1" slot="prepend" placeholder="请选择类型">
  139. <el-option v-for="(item, index) in integral_select" :key="index" :label="item.name" :value="item.value"></el-option>
  140. </el-select>
  141. </el-input>
  142. </el-form-item>
  143. <div v-if="rules_detail_form.range_type == 2" style="position: relative;bottom: 10px;padding: 0 10px;">至</div>
  144. <el-form-item v-if="rules_detail_form.range_type == 2" class="form-right select_width">
  145. <el-input placeholder="请输入分值" v-model.number="rules_detail_form.max_point" type="age" class="input-with-select">
  146. <el-select v-model="integral_select_name2" slot="prepend" placeholder="请选择类型">
  147. <el-option v-for="(item, index) in integral_select" :key="index" :label="item.name" :value="item.value"></el-option>
  148. </el-select>
  149. </el-input>
  150. </el-form-item>
  151. </div>
  152. <div class="flex-box flex-v-ce">
  153. <el-button type="danger" @click="del_rule" :loading="delRule_loading" :disabled="delRule_loading" v-show="rule_type == 'edit'">删除规则</el-button>
  154. <div class="flex-1"></div>
  155. <el-button @click="rule_close('rules_detail_form')">取消</el-button>
  156. <el-button type="primary" v-show="rule_type == 'add'" :loading="rule_loading2" :disabled="rule_loading2" @click="add_submit_rule('rules_detail_form')">
  157. 确定
  158. </el-button>
  159. <el-button type="primary" v-show="rule_type == 'edit'" :loading="rule_loading2" :disabled="rule_loading2" @click="edit_submit_rule('rules_detail_form')">
  160. 确定
  161. </el-button>
  162. </div>
  163. </el-form>
  164. </el-dialog>
  165. <!-- 导入规则 -->
  166. <!-- <el-dialog title="导入规则" :visible.sync="import_rules_show" width="500px" @before-close="close_import">
  167. <el-row>
  168. <el-col :span="12">
  169. <div class="text-center">
  170. <p>1、下载规则模版,填写好规则</p>
  171. <p><img src="@/assets/image/rules_mould.png" alt="" /></p>
  172. <p>规则表</p>
  173. <p>
  174. <a target="_blank" :href="downloadUrl"><el-button type="primary">下载模板</el-button></a>
  175. </p>
  176. </div>
  177. </el-col>
  178. <el-col :span="12">
  179. <div class="text-center">
  180. <p>2、上传填好的规则表</p>
  181. <p><img src="@/assets/image/rules_mould1.png" alt="" /></p>
  182. <p>仅支持xls、xlsx格式文件</p>
  183. <el-upload
  184. class="upload-demo"
  185. :headers="ATOKEN"
  186. ref="upload"
  187. :limit="1"
  188. :action="action"
  189. :on-remove="handleRemove"
  190. :on-success="handleSuccess"
  191. :before-upload="beforeFilesUpload"
  192. :file-list="fileList"
  193. >
  194. <el-button slot="trigger" type="primary">选取文件</el-button>
  195. </el-upload>
  196. </div>
  197. </el-col>
  198. </el-row>
  199. </el-dialog> -->
  200. <toLead :visible.sync="toleadShw" :nowIndex.sync="nowIndex" :tolead="toleadResult" @confirm="tealConfirm" :export_type="'rule_items'" :dstyle="'height:180px;padding: 40px 80px;'">
  201. <template slot="1">
  202. <el-row v-if="nowIndex == 1">
  203. <el-col :span="12">
  204. <div class="text-center">
  205. <p>1、下载规则模版,填写好规则</p>
  206. <p><img src="@/assets/image/rules_mould.png" alt="" /></p>
  207. <p>规则表</p>
  208. <span>
  209. <a target="_blank" :href="downloadUrl"><el-button type="primary">下载模板</el-button></a>
  210. </span>
  211. </div>
  212. </el-col>
  213. <el-col :span="12">
  214. <div class="text-center">
  215. <p>2、上传填好的规则表</p>
  216. <p><img src="@/assets/image/rules_mould1.png" alt="" /></p>
  217. <p>仅支持xls、xlsx格式文件</p>
  218. <el-upload
  219. class="upload-demo"
  220. :headers="ATOKEN"
  221. ref="upload"
  222. :limit="1"
  223. :action="action"
  224. :on-remove="handleRemove"
  225. :on-success="handleSuccess"
  226. :before-upload="beforeFilesUpload"
  227. :file-list="fileList"
  228. :on-progress="handleOnthecross"
  229. >
  230. <el-button slot="trigger" type="primary">选取文件</el-button>
  231. </el-upload>
  232. </div>
  233. </el-col>
  234. </el-row>
  235. </template>
  236. </toLead>
  237. </div>
  238. </template>
  239. <script>
  240. import QRCode from 'qrcodejs2';
  241. import toLead from '@/components/toLead';
  242. export default {
  243. data() {
  244. return {
  245. keyword:'',//搜索关键字
  246. ruleDetails: {},
  247. innerVisible: false,
  248. bodyLoad: false,
  249. action: process.env.VUE_APP_BASE_API + 'api/rule/import',
  250. downloadUrl: process.env.VUE_APP_BASE_API + 'api/download/rule_item',
  251. ATOKEN: { 'A-TOKEN': this.$getToken(), Accept: 'application/vnd.test.v2+json' },
  252. tips_show: true,
  253. rule_loading: false,
  254. rule_tree: [],
  255. item_list: [],
  256. all_item_list: [],
  257. defaultProps: {
  258. id: 'id',
  259. children: 'child',
  260. label: 'name'
  261. },
  262. selectItem: { name: '积分规则' }, //选择的分类
  263. //添加分类
  264. class_show: false,
  265. delRule_loading: false,
  266. dept_formdata_rules: {
  267. name: [
  268. {
  269. required: true,
  270. message: '请输入规则分类',
  271. trigger: 'blur'
  272. },
  273. {
  274. min: 2,
  275. max: 20,
  276. message: '长度在 2 到 20 个字符',
  277. trigger: 'blur'
  278. }
  279. ]
  280. },
  281. dept_formdata: {
  282. name: '',
  283. pid: '0',
  284. cycle_type: '1'
  285. },
  286. class_type: 'add',
  287. dept_loading: false,
  288. // 规则相关
  289. del_item_id: [], //选择规则ID集合
  290. rule_loading2: false,
  291. rule_type: 'add',
  292. rule_show: false,
  293. rules_detail_form: {
  294. rule_id: '',
  295. range_type: '1',
  296. prize_type: '0',
  297. min_point: '',
  298. max_point: '',
  299. min_point2: '',
  300. max_point2: '',
  301. remark: '',
  302. is_attendance: '0',
  303. cycle_type: '1',
  304. pt_id: 0
  305. },
  306. rules: {
  307. remark: [
  308. {
  309. required: true,
  310. message: '请输入规则名称',
  311. trigger: 'blur'
  312. }
  313. ],
  314. rule_id: [
  315. {
  316. required: true,
  317. message: '请选择分类',
  318. trigger: 'change'
  319. }
  320. ]
  321. },
  322. integral_select_name1: '1',
  323. integral_select_name2: '1',
  324. point_types: [],
  325. range_type_arr: [
  326. {
  327. name: '固定分值',
  328. value: '1'
  329. },
  330. {
  331. name: '范围分值',
  332. value: '2'
  333. }
  334. ],
  335. integral_select: [
  336. {
  337. name: '奖分',
  338. value: '1'
  339. },
  340. {
  341. name: '扣分',
  342. value: '2'
  343. }
  344. ],
  345. //导入规则
  346. import_rules_show: false,
  347. save_loading: false,
  348. import_btn_show: false,
  349. fileList: [],
  350. file: null,
  351. flName: '',
  352. // item_lists:[],
  353. //导入相关
  354. toleadShw: false,
  355. nowIndex: 1,
  356. toleadResult: {}
  357. };
  358. },
  359. components: {
  360. toLead
  361. },
  362. watch: {
  363. toleadShw(val){
  364. if(val) this.nowIndex = 1
  365. },
  366. 'dept_formdata.pid'(val, old_val) {
  367. this.$nextTick(() => {
  368. this.$refs.dept.dropDownVisible = false;
  369. });
  370. },
  371. 'rules_detail_form.rule_id'(val, old_val) {
  372. this.$nextTick(() => {
  373. this.$refs.dept2.dropDownVisible = false;
  374. });
  375. }
  376. },
  377. created() {
  378. this.point_types = this.$getTyps().reverse();
  379. },
  380. mounted() {
  381. this.$nextTick(function() {
  382. if (this.$getCache('rule')) {
  383. this.tips_show = false;
  384. } else {
  385. this.tips_show = true;
  386. }
  387. });
  388. var that = this;
  389. that.getData();
  390. },
  391. methods: {
  392. handleOnthecross(event, file, fileList){
  393. this.nowIndex = 2
  394. },
  395. //导出规则按钮
  396. derivedRule(){
  397. let userData=this.$getUserData();
  398. window.open(process.env.VUE_APP_BASE_API+'/api/download/rule_item/item?employee_id='+userData.id)
  399. },
  400. downloadE() {
  401. let rule_remark = '';
  402. if (this.ruleDetails.remark.length > 10) {
  403. rule_remark = this.ruleDetails.remark;
  404. rule_remark = rule_remark.slice(0, 10);
  405. } else {
  406. rule_remark = this.ruleDetails.remark;
  407. }
  408. var canvasData = this.$refs.qrcode.getElementsByTagName('canvas')
  409. var a = document.createElement("a");
  410. var event = new MouseEvent("click"); // 创建一个单击事件
  411. a.href = canvasData[0].toDataURL("image/png");
  412. a.download = rule_remark;
  413. a.dispatchEvent(event); // 触发a的单击事件
  414. },
  415. payOrder (row) {// 展示二维码
  416. let url = 'dingtalk://dingtalkclient/action/open_micro_app'
  417. let appid = '?appId='+this.$appId
  418. let corpId = '&corpId='+this.$getCache('corpId')
  419. // let corpId = '&corpId=ding011f57ab048cf202ffe93478753d9884'
  420. let page = '&page='+encodeURIComponent(`pages/workbench/apply/apply?id=${encodeURIComponent(row)}`)//encodeURIComponent('小米')
  421. let urls = url+appid+corpId+page
  422. var qrcode = new QRCode('qrcode', {
  423. text: urls, // 二维码内容
  424. width: 325,
  425. height: 325,
  426. render: 'table', // 设置渲染方式(有两种方式 table和canvas,默认是canvas)
  427. colorDark: '#34373e', // 二维码色
  428. colorLight: '#ffffff', // 背景色
  429. correctLevel: QRCode.CorrectLevel.H // 容错等级,H是heigh,最高,所以二维码看起来很密
  430. })
  431. },
  432. ruleQRcode(row) {
  433. this.ruleDetails = row;
  434. // 生成二维码
  435. this.innerVisible = true;
  436. // 使用$nextTick确保数据渲染
  437. this.$nextTick(() => {
  438. this.payOrder(row.id);
  439. });
  440. },
  441. // 关闭弹框,清除已经生成的二维码
  442. closeCode() {
  443. setTimeout(() => {
  444. this.$refs.qrcode.innerHTML = '';
  445. }, 150);
  446. },
  447. // 导入相关
  448. close_import() {
  449. this.import_rules_show = false;
  450. this.import_btn_show = false;
  451. this.$refs.upload.clearFiles();
  452. },
  453. submitUpload() {
  454. this.save_loading = true;
  455. let params = {
  456. file: this.file
  457. };
  458. this.$axios('post', '/api/rule/import', params)
  459. .then(res => {
  460. if (res.data.code == 1) {
  461. this.close_import();
  462. this.$message.success({ message: res.data.msg });
  463. this.getData();
  464. } else {
  465. this.$message({ type: 'error', message: res.data.msg });
  466. }
  467. })
  468. .finally(() => {
  469. this.save_loading = false;
  470. });
  471. },
  472. tealConfirm(){
  473. this.getData();
  474. },
  475. handleSuccess(response) {
  476. if(response.code == 1){
  477. response.data.id = 1
  478. }else{
  479. response.data.id = 0
  480. response.data.name = response.msg
  481. }
  482. this.toleadResult = response.data
  483. this.nowIndex = 3
  484. return
  485. if (response.code == 1) {
  486. if (response.data.length > 0) {
  487. var htmls = response.data;
  488. var str = "<div class='red'></div>";
  489. htmls.forEach(item => {
  490. str += `<div>${item.errors}</div>`;
  491. });
  492. this.close_import();
  493. this.$notify.error({
  494. title: '导入错误',
  495. dangerouslyUseHTMLString: true,
  496. message: str,
  497. duration: 0,
  498. offset: 50,
  499. customClass: 'notifyBox'
  500. });
  501. } else {
  502. this.file = response.data;
  503. this.$message.success({ message: response.msg });
  504. this.getData();
  505. this.close_import();
  506. }
  507. }else{
  508. this.$message.error({ message: response.msg });
  509. }
  510. },
  511. handleRemove(file, fileList) {
  512. if (fileList !== null && fileList.length != 0) {
  513. this.import_btn_show = true;
  514. } else {
  515. this.import_btn_show = false;
  516. }
  517. },
  518. beforeFilesUpload(file) {
  519. const $ext_list = ['xlsx', 'xls'];
  520. let len = file.name.split('.').length - 1;
  521. const $ext_name = file.name.split('.')[len];
  522. if ($ext_list.indexOf($ext_name) != -1) {
  523. } else {
  524. this.toleadResult.id = 0
  525. this.toleadResult.name = '文件格式上传错误,仅支持上传xlsx,xls)'
  526. this.nowIndex = 3
  527. return false;
  528. }
  529. },
  530. edit_submit_rule(form) {
  531. let self = this;
  532. self.$refs[form].validate(valid => {
  533. if (valid) {
  534. if (!self.rules_detail_form.min_point) {
  535. this.$message.error('积分不能为空或为0');
  536. return;
  537. }
  538. if (self.integral_select_name1 != '1' && self.rules_detail_form.min_point >= 0) {
  539. self.rules_detail_form.min_point = '-' + self.rules_detail_form.min_point;
  540. }
  541. if (self.integral_select_name2 != '1' && self.rules_detail_form.max_point >= 0) {
  542. self.rules_detail_form.max_point = '-' + self.rules_detail_form.max_point;
  543. }
  544. if (self.rules_detail_form.range_type == 1) {
  545. self.rules_detail_form.max_point = self.rules_detail_form.min_point;
  546. }
  547. if (Array.isArray(self.rules_detail_form.rule_id)) {
  548. self.rules_detail_form.rule_id = self.rules_detail_form.rule_id[self.rules_detail_form.rule_id.length - 1];
  549. }
  550. if (parseFloat(self.rules_detail_form.min_point) > parseFloat(self.rules_detail_form.max_point)) {
  551. this.$confirm(
  552. '填写的规则积分是' +
  553. self.rules_detail_form.min_point +
  554. ' ~ ' +
  555. self.rules_detail_form.max_point +
  556. ',应该是 ' +
  557. self.rules_detail_form.max_point +
  558. ' ~ ' +
  559. self.rules_detail_form.min_point +
  560. '吧?',
  561. '提示',
  562. {
  563. confirmButtonText: '确定',
  564. cancelButtonText: '取消',
  565. type: 'warning'
  566. }
  567. ).then(() => {
  568. this.rule_loading2 = true;
  569. let min_point = self.rules_detail_form.min_point;
  570. self.rules_detail_form.min_point = self.rules_detail_form.max_point;
  571. self.rules_detail_form.max_point = min_point;
  572. let data = self.rules_detail_form;
  573. data.item_id = self.rules_detail_form.id;
  574. if (self.rules_detail_form.min_point == 0 && self.rules_detail_form.range_type == 1) {
  575. self.$message.error('积分不能为零');
  576. this.rule_loading2 = false;
  577. return false;
  578. }
  579. this.$axios('post', '/api/integral/rule/items/edit', data)
  580. .then(res => {
  581. if (res.data.code == 1) {
  582. self.$message.success(res.data.msg);
  583. self.getData(true);
  584. self.rule_close(form);
  585. }
  586. })
  587. .finally(err => {
  588. this.rule_loading2 = false;
  589. });
  590. });
  591. } else {
  592. this.rule_loading2 = true;
  593. self.rules_detail_form.item_id = self.rules_detail_form.id;
  594. let data = self.rules_detail_form;
  595. data.item_id = self.rules_detail_form.id;
  596. if (self.rules_detail_form.min_point == 0 && self.rules_detail_form.range_type == 1) {
  597. self.$message.error('积分不能为零');
  598. this.rule_loading2 = false;
  599. return false;
  600. }
  601. this.$axios('post', '/api/integral/rule/items/edit', data)
  602. .then(res => {
  603. if (res.data.code == 1) {
  604. self.$message.success(res.data.msg);
  605. self.getData(true);
  606. self.rule_close(form);
  607. }
  608. })
  609. .finally(() => {
  610. this.rule_loading2 = false;
  611. });
  612. }
  613. } else {
  614. this.rule_loading2 = false;
  615. return false;
  616. }
  617. });
  618. },
  619. //添加规则
  620. add_submit_rule(form) {
  621. let self = this;
  622. self.$refs[form].validate(valid => {
  623. if (valid) {
  624. if (self.integral_select_name1 != '1' && self.rules_detail_form.min_point >= 0) {
  625. self.rules_detail_form.min_point = '-' + self.rules_detail_form.min_point;
  626. }
  627. if (self.integral_select_name2 != '1' && self.rules_detail_form.max_point >= 0) {
  628. self.rules_detail_form.max_point = '-' + self.rules_detail_form.max_point;
  629. }
  630. if (self.rules_detail_form.range_type == 1) {
  631. self.rules_detail_form.max_point = self.rules_detail_form.min_point;
  632. }
  633. if (self.rules_detail_form.min_point == 0 || !self.rules_detail_form.min_point || self.rules_detail_form.max_point == 0 || !self.rules_detail_form.max_point) {
  634. this.$message.error('积分不能为空或为0');
  635. return;
  636. }
  637. if (Array.isArray(self.rules_detail_form.rule_id)) {
  638. self.rules_detail_form.rule_id = self.rules_detail_form.rule_id[self.rules_detail_form.rule_id.length - 1];
  639. }
  640. if (parseFloat(self.rules_detail_form.min_point) > parseFloat(self.rules_detail_form.max_point)) {
  641. this.$confirm('填写的规则积分是' +self.rules_detail_form.min_point +' ~ ' +self.rules_detail_form.max_point +',应该是 ' +self.rules_detail_form.max_point +' ~ ' +self.rules_detail_form.min_point +'吧?','提示',
  642. {
  643. confirmButtonText: '确定',
  644. cancelButtonText: '取消',
  645. type: 'warning'
  646. }
  647. ).then(() => {
  648. this.rule_loading2 = true;
  649. let min_point = self.rules_detail_form.min_point;
  650. self.rules_detail_form.min_point = self.rules_detail_form.max_point;
  651. self.rules_detail_form.max_point = min_point;
  652. if (self.rules_detail_form.min_point == 0 && self.rules_detail_form.range_type == 1) {
  653. self.$message.error('积分不能为零');
  654. this.rule_loading2 = false;
  655. return false;
  656. }
  657. let data = {
  658. items: [self.rules_detail_form]
  659. };
  660. this.$axios('post', '/api/integral/rule/items', data)
  661. .then(res => {
  662. if (res.data.code == 1) {
  663. self.$message.success(res.data.msg);
  664. self.getData(true);
  665. self.rule_close(form);
  666. }
  667. })
  668. .finally(() => {
  669. this.rule_loading2 = false;
  670. });
  671. });
  672. } else {
  673. this.rule_loading2 = true;
  674. self.rules_detail_form.item_id = self.rules_detail_form.id;
  675. if (self.rules_detail_form.min_point == 0 && self.rules_detail_form.range_type == 1) {
  676. self.$message.error('积分不能为零');
  677. this.rule_loading2 = false;
  678. return false;
  679. }
  680. let data = {
  681. items: [self.rules_detail_form]
  682. };
  683. this.$axios('post', '/api/integral/rule/items', data)
  684. .then(res => {
  685. if (res.data.code == 1) {
  686. self.$message.success(res.data.msg);
  687. self.getData(true);
  688. self.rule_close(form);
  689. }
  690. })
  691. .finally(() => {
  692. this.rule_loading2 = false;
  693. });
  694. }
  695. } else {
  696. this.rule_loading2 = false;
  697. return false;
  698. }
  699. });
  700. },
  701. //删除规则
  702. del_rule() {
  703. let self = this;
  704. let data = {
  705. item_ids:JSON.stringify([this.rules_detail_form.id])
  706. };
  707. this.delRule_loading = true;
  708. const h = this.$createElement;
  709. self.$msgbox({
  710. title: '提示',
  711. message: h('div', null, [
  712. h('p', null, [
  713. h('i', { class: "el-icon-info", style: "color: #e6a23c; "}, null),
  714. h('span', { style: "font-size: 16px; color: black; padding-left: 5px;" }, '删除操作可能造成以下影响')
  715. ]),
  716. h('ul', { style: "list-style: disc; padding: 0 0 0 21px; color: #6d6d6d; margin: 5px 0; " },[
  717. h('li', {style: "margin: 5px 0;"}, '与当前积分规则关联的积分审批,以此规则作为依据的审批单只能作废'),
  718. h('li', {style: "margin: 5px 0;"}, '与当前积分规则关联的自定义积分排名,此规则产生的积分将不再统计'),
  719. ]),
  720. h('p', { style: "font-size: 15px; color: #616161; " }, '请确保无上述审批单或排名数据影响后,再操作删除'),
  721. ]),
  722. confirmButtonText: '确定',
  723. cancelButtonText: '取消',
  724. showCancelButton: true,
  725. customClass: 'winClass',//弹窗样式
  726. }).then(
  727. () => {
  728. this.$axios('post', '/api/integral/rule/items/destroy', data)
  729. .then(res => {
  730. if (res.data.code == 1) {
  731. self.$message.success(res.data.msg);
  732. self.rule_show = false;
  733. self.getData(true);
  734. }
  735. })
  736. .finally(() => {
  737. this.delRule_loading = false;
  738. });
  739. },
  740. err => {
  741. this.delRule_loading = false;
  742. }
  743. );
  744. },
  745. //关闭规则弹窗
  746. rule_close(form) {
  747. this.rule_show = false;
  748. this.$refs[form].resetFields();
  749. },
  750. not_data() {
  751. this.$confirm('暂时没有积分分类,是否前往添加?', '提示', {
  752. confirmButtonText: '确定',
  753. cancelButtonText: '取消',
  754. type: 'warning'
  755. }).then(() => {
  756. this.rule_show = false;
  757. this.class_show = true;
  758. });
  759. },
  760. add_rule() {
  761. this.rule_show = true;
  762. this.rule_type = 'add';
  763. this.rules_detail_form = {
  764. rule_id: '',
  765. range_type: '1',
  766. prize_type: '0',
  767. min_point: '',
  768. max_point: '',
  769. min_point2: '',
  770. max_point2: '',
  771. remark: '',
  772. is_attendance: '0',
  773. cycle_type: '1',
  774. pt_id: 3
  775. };
  776. this.integral_select_name1 = '1';
  777. this.integral_select_name2 = '1';
  778. },
  779. //批量删除
  780. del_item() {
  781. if (this.del_item_id.length == 0) {
  782. this.$message.error('请选择积分细则');
  783. return false;
  784. }
  785. const h = this.$createElement;
  786. this.$msgbox({
  787. title: '提示',
  788. message: h('div', null, [
  789. h('p', null, [
  790. h('i', { class: "el-icon-info", style: "color: #e6a23c; "}, null),
  791. h('span', { style: "font-size: 16px; color: black; padding-left: 5px;" }, '删除操作可能造成以下影响')
  792. ]),
  793. h('ul', { style: "list-style: disc; padding: 0 0 0 21px; color: #6d6d6d; margin: 5px 0; " },[
  794. h('li', {style: "margin: 5px 0;"}, '与当前积分规则关联的积分审批,以此规则作为依据的审批单只能作废'),
  795. h('li', {style: "margin: 5px 0;"}, '与当前积分规则关联的自定义积分排名,此规则产生的积分将不再统计'),
  796. ]),
  797. h('p', { style: "font-size: 15px; color: #616161; " }, '请确保无上述审批单或排名数据影响后,再操作删除'),
  798. ]),
  799. confirmButtonText: '确定',
  800. cancelButtonText: '取消',
  801. showCancelButton: true,
  802. customClass: 'winClass',//弹窗样式
  803. }).then(() => {
  804. let data = {
  805. item_ids: JSON.stringify(this.del_item_id)
  806. };
  807. this.$axios('post', '/api/integral/rule/items/destroy', data).then(res => {
  808. if (res.data.code == 1) {
  809. this.$message.success(res.data.msg);
  810. this.getData(true);
  811. }
  812. });
  813. });
  814. },
  815. editDetails(val) {
  816. this.rules_detail_form = JSON.parse(JSON.stringify(val));
  817. if (this.rules_detail_form.min_point == this.rules_detail_form.max_point) {
  818. this.rules_detail_form.range_type = '1';
  819. } else {
  820. this.rules_detail_form.range_type = '2';
  821. }
  822. if (this.rules_detail_form.min_point < 0) {
  823. this.integral_select_name1 = '2';
  824. let str = this.rules_detail_form.min_point;
  825. this.rules_detail_form.min_point = str.toString().substring(1);
  826. } else {
  827. this.integral_select_name1 = '1';
  828. }
  829. if (this.rules_detail_form.max_point < 0) {
  830. this.integral_select_name2 = '2';
  831. let str = this.rules_detail_form.max_point;
  832. this.rules_detail_form.max_point = str.toString().substring(1);
  833. } else {
  834. this.integral_select_name2 = '1';
  835. }
  836. this.rule_show = true;
  837. this.rule_type = 'edit';
  838. },
  839. handleSelectionChange(val) {
  840. this.del_item_id = [];
  841. val.forEach(element => {
  842. this.del_item_id.push(element.id);
  843. });
  844. },
  845. handleNodeClick(e) {
  846. if(e.id){
  847. var items = this.getItemData(e);
  848. this.selectItem = {
  849. child: e.child,
  850. id: e.id,
  851. name: e.name,
  852. pid: e.pid
  853. };
  854. this.flName = e.name;
  855. this.item_list = items;
  856. }else{
  857. this.selectItem = { name: '积分规则' };
  858. }
  859. },
  860. getItemData(e) {
  861. var ids = [];
  862. var lists = [];
  863. if (e.child && e.child.length > 0) {
  864. ids.push(e.id);
  865. e.child.map(item => {
  866. ids.push(item.id);
  867. if (item.child && item.child.length > 0) {
  868. item.child.map(item1 => {
  869. ids.push(item1.id);
  870. if (item1.child && item1.child.length > 0) {
  871. item1.child.map(item2 => {
  872. ids.push(item2.id);
  873. });
  874. }
  875. });
  876. }
  877. });
  878. for (var i = 0; i < ids.length; i++) {
  879. lists.push(...this.filterItem(ids[i]));
  880. }
  881. } else {
  882. lists = this.filterItem(e.id);
  883. }
  884. return lists;
  885. },
  886. //根据分类ID获取对应的规则
  887. filterItem(id) {
  888. var all_item_list = this.all_item_list;
  889. var items = all_item_list.filter(item => {
  890. return item.rule_id == id;
  891. });
  892. return items;
  893. },
  894. //点击搜索
  895. onFilterChanged: function() {
  896. this.getData(true)
  897. },
  898. getData(is) {
  899. this.rule_loading = true;
  900. this.$axios('get', '/api/integral/rule/trees', { cycle_type: 1 , keyword:this.keyword})
  901. .then(res => {
  902. var item_list = res.data.data.item_list || [];
  903. var list = [];
  904. for (let i in item_list) {
  905. for (let k in item_list[i]) {
  906. item_list[i][k].pt_Obj = this.$getTyps(item_list[i][k].pt_id);
  907. list.push(item_list[i][k]);
  908. }
  909. }
  910. this.rule_tree = res.data.data.rule_tree || [];
  911. this.item_list = list;
  912. this.all_item_list = list;
  913. if (is) {
  914. this.handleNodeClick(this.selectItem);
  915. } else {
  916. this.selectItem = { name: '积分规则' }; //选择的分类
  917. }
  918. })
  919. .finally(() => {
  920. this.rule_loading = false;
  921. });
  922. },
  923. //编辑分组
  924. edit_class() {
  925. this.class_show = true;
  926. this.class_type = 'edit';
  927. this.dept_formdata = {
  928. child: this.selectItem.child,
  929. id: this.selectItem.id,
  930. name: this.selectItem.name,
  931. pid: this.selectItem.pid
  932. };
  933. },
  934. //添加分组
  935. submit_add_dept(form) {
  936. this.dept_loading = true;
  937. let that = this;
  938. that.$refs[form].validate(valid => {
  939. if (valid) {
  940. let pidData=JSON.parse(JSON.stringify(that.dept_formdata.pid))//备份选择的规则,因为提交时间PID会被重新赋值
  941. if (that.class_type == 'edit') {
  942. delete that.dept_formdata.child;
  943. that.dept_formdata.rule_id = that.dept_formdata.id;
  944. if (typeof that.dept_formdata.pid == 'number') {
  945. } else {
  946. if (that.dept_formdata.pid.length > 0) {
  947. that.dept_formdata.pid = that.dept_formdata.pid[that.dept_formdata.pid.length - 1];
  948. } else {
  949. that.dept_formdata.pid = 0;
  950. }
  951. }
  952. this.$axios('post', '/api/integral/rule/edit', that.dept_formdata)
  953. .then(res => {
  954. if (res.data.code == 1) {
  955. that.selectItem.name = that.dept_formdata.name;
  956. that.$message.success('修改积分分类成功');
  957. this.getData(true);
  958. this.add_dept_close('dept_formdata');
  959. }
  960. })
  961. .finally(() => {
  962. this.dept_formdata.pid=pidData
  963. this.dept_loading = false;
  964. });
  965. } else {
  966. if (that.dept_formdata.pid !== null && that.dept_formdata.pid.length == 0) {
  967. that.dept_formdata.pid = 0;
  968. } else {
  969. that.dept_formdata.pid = that.dept_formdata.pid[that.dept_formdata.pid.length - 1];
  970. }
  971. this.$axios('post', '/api/integral/rule', that.dept_formdata)
  972. .then(res => {
  973. if (res.data.code == 1) {
  974. that.$message.success('添加积分分类成功');
  975. this.getData(true);
  976. this.add_dept_close('dept_formdata');
  977. }
  978. })
  979. .finally(() => {
  980. this.dept_formdata.pid=pidData
  981. this.dept_loading = false;
  982. });
  983. }
  984. } else {
  985. this.dept_loading = false;
  986. }
  987. });
  988. },
  989. //删除分组
  990. del_dept() {
  991. this.$confirm('此操作将永久删除该分组, 是否继续?', '提示', {
  992. confirmButtonText: '确定',
  993. cancelButtonText: '取消',
  994. type: 'warning'
  995. }).then(() => {
  996. this.$axios('post', '/api/integral/rule/destroy', { rule_id: this.selectItem.id }).then(res => {
  997. if (res.data.code == 1) {
  998. this.$message.success(res.data.msg);
  999. this.getData();
  1000. this.add_dept_close('dept_formdata');
  1001. }
  1002. });
  1003. });
  1004. },
  1005. //关闭弹窗
  1006. add_dept_close(form) {
  1007. this.class_show = false;
  1008. this.$refs[form].resetFields();
  1009. },
  1010. //关闭提示
  1011. tips_close() {
  1012. this.$setCache('rule', 'true');
  1013. this.tips_show = false;
  1014. },
  1015. //添加分类
  1016. add_class() {
  1017. this.class_show = true;
  1018. this.class_type = 'add';
  1019. this.dept_formdata = {
  1020. name: '',
  1021. pid: '0',
  1022. cycle_type: '1'
  1023. };
  1024. }
  1025. }
  1026. };
  1027. </script>
  1028. <style scoped lang="scss">
  1029. $red: #f56c6c;
  1030. ::v-deep .el-table__row{
  1031. cursor: pointer;
  1032. }
  1033. .select_width .el-select {
  1034. width: 80px;
  1035. background-color: #fff;
  1036. border: 1px solid #f1f1f1;
  1037. border-left: none;
  1038. color: #222;
  1039. border-radius: 5px;
  1040. }
  1041. .text-center {
  1042. text-align: center;
  1043. }
  1044. .text-center p {
  1045. padding: 10px 0;
  1046. }
  1047. .terr-right {
  1048. .name {
  1049. font-size: 18px;
  1050. margin-right: 20px;
  1051. }
  1052. .btns button {
  1053. font-size: 14px;
  1054. height: 38px;
  1055. width: 90px;
  1056. margin-top: 20px;
  1057. margin-right: 5px;
  1058. }
  1059. }
  1060. .rule_class_box {
  1061. ::v-deep .el-tree-node {
  1062. border-bottom: 1px #f8f8f8 solid;
  1063. }
  1064. ::v-deep .el-tree-node__content {
  1065. padding: 10px 0;
  1066. // border-bottom: 1px #f8f8f8 solid;
  1067. }
  1068. ::v-deep .el-tree-node__content:hover {
  1069. background: #ecf5ff;
  1070. border-radius: 4px;
  1071. }
  1072. ::v-deep .is-current .el-tree-node__content .el-icon-caret-right {
  1073. color: #409eff !important;
  1074. }
  1075. ::v-deep .is-current .el-tree-node__content .el-tree-node__label {
  1076. color: #409eff !important;
  1077. }
  1078. ::v-deep .is-current .el-tree-node__children .el-icon-caret-right {
  1079. color: #c0c4cc !important;
  1080. }
  1081. ::v-deep .is-current .el-tree-node__children .el-tree-node__label {
  1082. color: #606266 !important;
  1083. }
  1084. ::v-deep .el-tree-node__label {
  1085. overflow: hidden;
  1086. text-overflow: ellipsis;
  1087. white-space: nowrap;
  1088. }
  1089. }
  1090. .form-right ::v-deep .el-form-item__content {
  1091. margin-left: 0px !important;
  1092. }
  1093. .terr-left button {
  1094. margin: 0 auto;
  1095. display: block;
  1096. margin-bottom: 20px;
  1097. }
  1098. .el-dropdown-links {
  1099. font-size: 20px;
  1100. cursor: pointer;
  1101. color: #686a6d;
  1102. }
  1103. .color-red {
  1104. color: $red;
  1105. &:hover {
  1106. color: #f14141;
  1107. }
  1108. }
  1109. .qrcodesave {
  1110. text-align: center;
  1111. margin-top: 15px;
  1112. font-size: 18px;
  1113. span {
  1114. color: #606266;
  1115. cursor: pointer;
  1116. transition: all 0.3s;
  1117. }
  1118. }
  1119. .qrcodesave span:hover {
  1120. color: #2490fd;
  1121. }
  1122. .lookQrcode {
  1123. color: #606266;
  1124. cursor: pointer;
  1125. transition: all 0.3s;
  1126. }
  1127. .lookQrcode:hover {
  1128. color: #2490fd;
  1129. }
  1130. .ruleSearch ::v-deep .el-input__inner{
  1131. height:38px;
  1132. }
  1133. </style>
  1134. <style lang="scss">
  1135. .winClass{
  1136. width: 500px
  1137. }
  1138. </style>