school_config.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <template>
  2. <el-container>
  3. <el-main class="el-main-padding">
  4. <el-form
  5. ref="ruleForm"
  6. :model="ruleForm"
  7. :rules="rules"
  8. label-width="200px"
  9. class="demo-ruleForm"
  10. :inline-message="true"
  11. >
  12. <el-form-item v-if="isSuperAdmin" label="学校">
  13. <el-select
  14. v-model="ruleForm.orgId"
  15. placeholder="请选择"
  16. style="width: 180px"
  17. filterable
  18. >
  19. <el-option
  20. v-for="item in rootSchoolSelect"
  21. :key="item.id"
  22. :label="item.name"
  23. :value="item.id"
  24. />
  25. </el-select>
  26. </el-form-item>
  27. <el-form-item
  28. label="使用第三方登录"
  29. prop="STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY"
  30. >
  31. <el-switch
  32. v-model="ruleForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY"
  33. on-text="是"
  34. off-text="否"
  35. ></el-switch>
  36. </el-form-item>
  37. <el-form-item
  38. label="第三方登录页地址"
  39. prop="STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL"
  40. >
  41. <el-input
  42. v-model="ruleForm.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL"
  43. :disabled="!ruleForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY"
  44. placeholder="请输入第三方登录页地址,以http://或https://开头"
  45. class="input-width"
  46. ></el-input>
  47. </el-form-item>
  48. <el-form-item label="展示我司logo" prop="SHOW_QMTH_LOGO">
  49. <el-switch
  50. v-model="ruleForm.SHOW_QMTH_LOGO"
  51. on-text="是"
  52. off-text="否"
  53. ></el-switch>
  54. </el-form-item>
  55. <el-form-item label="证件号隐私模式" prop="ID_NUMBER_PRIVATE_MODE">
  56. <el-switch
  57. v-model="ruleForm.ID_NUMBER_PRIVATE_MODE"
  58. on-text="是"
  59. off-text="否"
  60. ></el-switch>
  61. </el-form-item>
  62. <el-form-item
  63. label="展示APP下载二维码"
  64. prop="SHOW_STUDENT_CLIENT_APP_QRCODE"
  65. >
  66. <el-switch
  67. v-model="ruleForm.SHOW_STUDENT_CLIENT_APP_QRCODE"
  68. on-text="是"
  69. off-text="否"
  70. ></el-switch>
  71. </el-form-item>
  72. <el-form-item label="开放APP" prop="APP_ENABLED">
  73. <el-switch
  74. v-model="ruleForm.APP_ENABLED"
  75. on-text="是"
  76. off-text="否"
  77. ></el-switch>
  78. </el-form-item>
  79. <el-form-item label="开放微信小程序作答" prop="WEIXIN_ANSWER_ENABLED">
  80. <el-switch
  81. v-model="ruleForm.WEIXIN_ANSWER_ENABLED"
  82. on-text="是"
  83. off-text="否"
  84. ></el-switch>
  85. </el-form-item>
  86. <el-form-item
  87. label="活体检测方案"
  88. prop="IDENTIFICATION_OF_LIVING_BODY_SCHEME"
  89. >
  90. <el-radio-group
  91. v-model="ruleForm.IDENTIFICATION_OF_LIVING_BODY_SCHEME"
  92. class="input"
  93. >
  94. <el-radio label="S1" :disabled="ruleForm.PC_CLIENT_ENABLED"
  95. >FaceID</el-radio
  96. >
  97. <el-radio label="S2" :disabled="ruleForm.PC_CLIENT_ENABLED"
  98. >自研活体</el-radio
  99. >
  100. <el-radio label="S3" :disabled="!ruleForm.PC_CLIENT_ENABLED"
  101. >C端活体</el-radio
  102. >
  103. </el-radio-group>
  104. </el-form-item>
  105. <el-form-item label="启用C端考生端" prop="PC_CLIENT_ENABLED">
  106. <el-switch
  107. v-model="ruleForm.PC_CLIENT_ENABLED"
  108. on-text="是"
  109. off-text="否"
  110. :disabled="false"
  111. ></el-switch>
  112. </el-form-item>
  113. <div v-if="ruleForm.PC_CLIENT_ENABLED">
  114. <el-form-item label="指定动作检测提醒" prop="ACTION_ALERT">
  115. <el-input
  116. v-model="ruleForm.ACTION_ALERT"
  117. style="width: 180px"
  118. ></el-input>
  119. <span style="font-size: 14px; line-height: 44px">
  120. 秒后开始检测</span
  121. >
  122. </el-form-item>
  123. <el-form-item label="动作个数" prop="ACTION_NUM">
  124. <el-select v-model="ruleForm.ACTION_NUM" style="width: 180px">
  125. <el-option label="1" value="1"></el-option>
  126. <el-option label="2" value="2"></el-option>
  127. <el-option label="3" value="3"></el-option>
  128. </el-select>
  129. </el-form-item>
  130. <el-form-item label="动作选项" prop="ACTION_OPTIONS">
  131. <el-checkbox-group v-model="ruleForm.ACTION_OPTIONS">
  132. <el-checkbox
  133. v-for="opt in actionOptions"
  134. :key="opt.code"
  135. v-model="opt.code"
  136. name="ACTION_OPTION"
  137. :label="opt.code"
  138. >{{ opt.name }}</el-checkbox
  139. >
  140. </el-checkbox-group>
  141. </el-form-item>
  142. <el-form-item label="动作顺序" prop="ACTION_ORDER">
  143. <el-radio-group v-model="ruleForm.ACTION_ORDER" class="input">
  144. <el-radio label="RANDOM">随机</el-radio>
  145. <el-radio label="FIXED">固定</el-radio>
  146. </el-radio-group>
  147. </el-form-item>
  148. <el-form-item label="单个动作最大时长" prop="ACTION_DURATION">
  149. <el-input
  150. v-model="ruleForm.ACTION_DURATION"
  151. style="width: 180px"
  152. ></el-input>
  153. <span style="font-size: 14px; line-height: 44px"> 秒</span>
  154. </el-form-item>
  155. </div>
  156. <el-form-item>
  157. <el-button
  158. :disabled="btnSaveDiabled"
  159. type="primary"
  160. @click="submitForm('ruleForm')"
  161. >保 存</el-button
  162. >
  163. </el-form-item>
  164. </el-form>
  165. </el-main>
  166. </el-container>
  167. </template>
  168. <script>
  169. import { mapState } from "vuex";
  170. import { ACTION_OPTION_LIST, CORE_API } from "@/constants/constants.js";
  171. export default {
  172. data() {
  173. var validateUrl = (rule, value, callback) => {
  174. var ass = this.ruleForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY;
  175. var reg = /^(http:\/\/|https:\/\/){1}.*$/;
  176. if (ass && !value) {
  177. return callback(new Error("请输入第三方登录页地址"));
  178. } else if (ass && !value.match(reg)) {
  179. return callback(new Error("url以http://或https://开头"));
  180. } else {
  181. callback();
  182. }
  183. };
  184. let checkFaceType = (rule, value, callback) => {
  185. if (this.ruleForm.PC_CLIENT_ENABLED) {
  186. if (value != "S3") {
  187. return callback(new Error("请选择可用的 “活体检测方案”"));
  188. }
  189. } else {
  190. if (value == "S3") {
  191. return callback(new Error("请选择可用的 “活体检测方案”"));
  192. }
  193. }
  194. callback();
  195. };
  196. let checkActionOptions = (rule, value, callback) => {
  197. let pcClientEnabled = this.ruleForm.PC_CLIENT_ENABLED;
  198. if (pcClientEnabled) {
  199. if (this.ruleForm.ACTION_NUM != this.ruleForm.ACTION_OPTIONS.length) {
  200. return callback(new Error("动作个数与动作选项数量不一致"));
  201. }
  202. }
  203. callback();
  204. };
  205. let checkDuration = (rule, value, callback) => {
  206. let pcClientEnabled = this.ruleForm.PC_CLIENT_ENABLED;
  207. if (pcClientEnabled) {
  208. let reg = /^[1-9][0-9]*$/;
  209. if (!value.match(reg) || value < 5 || value > 20) {
  210. return callback(new Error("范围5至20之间"));
  211. }
  212. }
  213. callback();
  214. };
  215. return {
  216. actionOptions: ACTION_OPTION_LIST,
  217. rootOrgList: [],
  218. propertyGroupId: "",
  219. formDataChanged: false,
  220. originalRuleForm: {},
  221. ruleForm: {
  222. relatedPropertyGroupIdList: [],
  223. orgId: null,
  224. STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY: false,
  225. SHOW_STUDENT_CLIENT_APP_QRCODE: false,
  226. STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL: "",
  227. SHOW_QMTH_LOGO: false,
  228. ID_NUMBER_PRIVATE_MODE: false,
  229. APP_ENABLED: false,
  230. WEIXIN_ANSWER_ENABLED: false,
  231. IDENTIFICATION_OF_LIVING_BODY_SCHEME: "",
  232. PC_CLIENT_ENABLED: false,
  233. ACTION_ALERT: "",
  234. ACTION_NUM: "",
  235. ACTION_OPTIONS: [],
  236. ACTION_ORDER: "",
  237. ACTION_DURATION: "",
  238. },
  239. rules: {
  240. STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL: [
  241. {
  242. validator: validateUrl,
  243. trigger: "change",
  244. },
  245. ],
  246. IDENTIFICATION_OF_LIVING_BODY_SCHEME: [
  247. {
  248. validator: checkFaceType,
  249. trigger: "change",
  250. },
  251. ],
  252. ACTION_OPTIONS: [
  253. {
  254. validator: checkActionOptions,
  255. trigger: "change",
  256. },
  257. ],
  258. ACTION_ALERT: [
  259. { required: true, message: " ", trigger: "blur" },
  260. {
  261. validator: checkDuration,
  262. trigger: "blur",
  263. },
  264. ],
  265. ACTION_DURATION: [
  266. { required: true, message: " ", trigger: "blur" },
  267. {
  268. validator: checkDuration,
  269. trigger: "blur",
  270. },
  271. ],
  272. },
  273. };
  274. },
  275. computed: {
  276. ...mapState({ user: (state) => state.user }),
  277. btnSaveDiabled() {
  278. console.log(this.formDataChanged);
  279. return !this.formDataChanged;
  280. },
  281. isSuperAdmin() {
  282. return this.user.roleList.some((role) => role.roleCode == "SUPER_ADMIN");
  283. },
  284. rootSchoolSelect() {
  285. let rootSchools = [];
  286. for (let i = 0; i < this.rootOrgList.length; i++) {
  287. let info = {
  288. name: this.rootOrgList[i].name + "(" + this.rootOrgList[i].id + ")",
  289. id: this.rootOrgList[i].id,
  290. };
  291. rootSchools.push(info);
  292. }
  293. return rootSchools;
  294. },
  295. },
  296. watch: {
  297. "ruleForm.orgId": {
  298. handler: function () {
  299. this.initForm();
  300. },
  301. },
  302. "ruleForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY": {
  303. handler: function (val) {
  304. this.$refs["ruleForm"].validate();
  305. if (!val) {
  306. this.ruleForm.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL = "";
  307. }
  308. },
  309. },
  310. ruleForm: {
  311. deep: true,
  312. handler: function (newForm) {
  313. if (Object.keys(this.originalRuleForm).length > 0) {
  314. this.formDataChanged = !(
  315. newForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY ==
  316. this.originalRuleForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY &&
  317. newForm.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL ==
  318. this.originalRuleForm.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL &&
  319. newForm.SHOW_QMTH_LOGO == this.originalRuleForm.SHOW_QMTH_LOGO &&
  320. newForm.ID_NUMBER_PRIVATE_MODE ==
  321. this.originalRuleForm.ID_NUMBER_PRIVATE_MODE &&
  322. newForm.APP_ENABLED == this.originalRuleForm.APP_ENABLED &&
  323. newForm.WEIXIN_ANSWER_ENABLED ==
  324. this.originalRuleForm.WEIXIN_ANSWER_ENABLED &&
  325. newForm.SHOW_STUDENT_CLIENT_APP_QRCODE ==
  326. this.originalRuleForm.SHOW_STUDENT_CLIENT_APP_QRCODE &&
  327. newForm.IDENTIFICATION_OF_LIVING_BODY_SCHEME ==
  328. this.originalRuleForm.IDENTIFICATION_OF_LIVING_BODY_SCHEME &&
  329. newForm.PC_CLIENT_ENABLED ==
  330. this.originalRuleForm.PC_CLIENT_ENABLED &&
  331. newForm.ACTION_ALERT == this.originalRuleForm.ACTION_ALERT &&
  332. newForm.ACTION_OPTIONS == this.originalRuleForm.ACTION_OPTIONS &&
  333. newForm.ACTION_ORDER == this.originalRuleForm.ACTION_ORDER &&
  334. newForm.ACTION_DURATION == this.originalRuleForm.ACTION_DURATION
  335. );
  336. } else {
  337. this.formDataChanged = false;
  338. }
  339. },
  340. },
  341. },
  342. created() {
  343. this.ruleForm.orgId = this.user.rootOrgId;
  344. this.propertyGroupId = "config4Edit1";
  345. if (this.isSuperAdmin) {
  346. this.$httpWithMsg
  347. .get(CORE_API + "/org/getRootOrgList")
  348. .then((response) => {
  349. this.rootOrgList = response.data;
  350. });
  351. }
  352. this.initForm();
  353. },
  354. methods: {
  355. submitForm(formName) {
  356. this.$refs[formName].validate((valid) => {
  357. if (valid) {
  358. let params = {
  359. orgId: null,
  360. relatedPropertyGroupIdList: [],
  361. properties: {},
  362. };
  363. params.orgId = this.ruleForm.orgId;
  364. params.relatedPropertyGroupIdList =
  365. this.ruleForm.relatedPropertyGroupIdList;
  366. params.properties.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY =
  367. this.ruleForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY;
  368. params.properties.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL =
  369. this.ruleForm.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL;
  370. params.properties.SHOW_QMTH_LOGO = this.ruleForm.SHOW_QMTH_LOGO;
  371. params.properties.ID_NUMBER_PRIVATE_MODE =
  372. this.ruleForm.ID_NUMBER_PRIVATE_MODE;
  373. params.properties.APP_ENABLED = this.ruleForm.APP_ENABLED;
  374. params.properties.WEIXIN_ANSWER_ENABLED =
  375. this.ruleForm.WEIXIN_ANSWER_ENABLED;
  376. params.properties.SHOW_STUDENT_CLIENT_APP_QRCODE =
  377. this.ruleForm.SHOW_STUDENT_CLIENT_APP_QRCODE;
  378. params.properties.IDENTIFICATION_OF_LIVING_BODY_SCHEME =
  379. this.ruleForm.IDENTIFICATION_OF_LIVING_BODY_SCHEME;
  380. params.properties.PC_CLIENT_ENABLED = this.ruleForm.PC_CLIENT_ENABLED;
  381. if (params.properties.PC_CLIENT_ENABLED) {
  382. params.properties.ACTION_ALERT = this.ruleForm.ACTION_ALERT;
  383. params.properties.ACTION_NUM = this.ruleForm.ACTION_NUM;
  384. params.properties.ACTION_OPTIONS =
  385. this.ruleForm.ACTION_OPTIONS.join(",");
  386. params.properties.ACTION_ORDER = this.ruleForm.ACTION_ORDER;
  387. params.properties.ACTION_DURATION = this.ruleForm.ACTION_DURATION;
  388. }
  389. this.$httpWithMsg
  390. .put(CORE_API + "/org/saveOrgProperties", params)
  391. .then(
  392. () => {
  393. this.$notify({
  394. message: "保存成功",
  395. type: "success",
  396. });
  397. this.originalRuleForm = Object.assign({}, this.ruleForm);
  398. this.formDataChanged = false;
  399. },
  400. () => {}
  401. );
  402. } else {
  403. return false;
  404. }
  405. });
  406. },
  407. initForm() {
  408. this.ruleForm.relatedPropertyGroupIdList = ["studentClientConfig"];
  409. var url =
  410. CORE_API +
  411. "/org/getOrgPropertiesByGroupWithoutCache/" +
  412. this.ruleForm.orgId +
  413. "/" +
  414. this.propertyGroupId;
  415. this.$httpWithMsg.get(url).then((response) => {
  416. if (response) {
  417. this.ruleForm.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY =
  418. response.data.STUDENT_CLIENT_ACCESS_FROM_THIRD_PARTY == "true";
  419. this.ruleForm.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL =
  420. response.data.STUDENT_CLIENT_THIRD_PARTY_LOGIN_URL;
  421. this.ruleForm.SHOW_QMTH_LOGO = response.data.SHOW_QMTH_LOGO == "true";
  422. this.ruleForm.ID_NUMBER_PRIVATE_MODE =
  423. response.data.ID_NUMBER_PRIVATE_MODE == "true";
  424. this.ruleForm.APP_ENABLED = response.data.APP_ENABLED == "true";
  425. this.ruleForm.WEIXIN_ANSWER_ENABLED =
  426. response.data.WEIXIN_ANSWER_ENABLED == "true";
  427. this.ruleForm.SHOW_STUDENT_CLIENT_APP_QRCODE =
  428. response.data.SHOW_STUDENT_CLIENT_APP_QRCODE == "true";
  429. this.ruleForm.IDENTIFICATION_OF_LIVING_BODY_SCHEME =
  430. response.data.IDENTIFICATION_OF_LIVING_BODY_SCHEME;
  431. // 未配置时,赋默认值
  432. this.ruleForm.PC_CLIENT_ENABLED =
  433. "true" == response.data.PC_CLIENT_ENABLED;
  434. if (response.data.ACTION_ALERT) {
  435. this.ruleForm.ACTION_ALERT = response.data.ACTION_ALERT;
  436. } else {
  437. this.ruleForm.ACTION_ALERT = 15;
  438. }
  439. if (response.data.ACTION_NUM) {
  440. this.ruleForm.ACTION_NUM = response.data.ACTION_NUM;
  441. } else {
  442. this.ruleForm.ACTION_NUM = 2;
  443. }
  444. if (response.data.ACTION_OPTIONS) {
  445. this.ruleForm.ACTION_OPTIONS =
  446. response.data.ACTION_OPTIONS.split(",");
  447. } else {
  448. this.ruleForm.ACTION_OPTIONS = ["NOD", "SHAKE"];
  449. }
  450. if (response.data.ACTION_ORDER) {
  451. this.ruleForm.ACTION_ORDER = response.data.ACTION_ORDER;
  452. } else {
  453. this.ruleForm.ACTION_ORDER = "RANDOM";
  454. }
  455. if (response.data.ACTION_DURATION) {
  456. this.ruleForm.ACTION_DURATION = response.data.ACTION_DURATION;
  457. } else {
  458. this.ruleForm.ACTION_DURATION = 15;
  459. }
  460. this.originalRuleForm = Object.assign({}, this.ruleForm);
  461. } else {
  462. this.$notify({
  463. message: "学校设置信息暂未初始化,请立即初始化",
  464. type: "warning",
  465. });
  466. }
  467. });
  468. },
  469. },
  470. };
  471. </script>
  472. <style scoped>
  473. .input-width {
  474. width: 638px;
  475. }
  476. </style>