| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188 | <template>  <div class="app-container">    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">      <el-form-item label="模板名称" prop="name">        <el-input          v-model="queryParams.name"          placeholder="请输入模板名称"          clearable          size="small"          @keyup.enter.native="handleQuery"        />      </el-form-item>      <el-form-item label="状态" prop="status">        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">          <el-option            v-for="dict in statusOptions"            :key="dict.dictValue"            :label="dict.dictLabel"            :value="dict.dictValue"          />        </el-select>      </el-form-item>      <el-form-item label="课程" prop="courseId">        <el-input          v-model="queryParams.courseId"          placeholder="请输入课程id"          clearable          size="small"          @keyup.enter.native="handleQuery"        />      </el-form-item>      <el-form-item label="小节" prop="videoId">        <el-input          v-model="queryParams.videoId"          placeholder="请输入小节视频id"          clearable          size="small"          @keyup.enter.native="handleQuery"        />      </el-form-item>      <el-form-item>        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>      </el-form-item>    </el-form>    <el-row :gutter="10" class="mb8">      <el-col :span="1.5">        <el-button          type="primary"          plain          icon="el-icon-plus"          size="mini"          @click="handleAdd"          v-hasPermi="['courseFinishTemp:course:add']"        >新增        </el-button>      </el-col>     <el-col :span="1.5">       <el-button         type="success"         plain         icon="el-icon-edit"         size="mini"         :disabled="multiple"         @click="handleUpdateStatusBatch"         v-hasPermi="['courseFinishTemp:course:edit']"       >批量修改状态       </el-button>     </el-col>      <el-col :span="1.5">        <el-button          type="danger"          plain          icon="el-icon-delete"          size="mini"          :disabled="multiple"          @click="handleDelete"          v-hasPermi="['courseFinishTemp:course:remove']"        >删除        </el-button>      </el-col>      <el-col :span="1.5">        <el-button          type="warning"          plain          icon="el-icon-download"          size="mini"          :loading="exportLoading"          @click="handleExport"          v-hasPermi="['courseFinishTemp:course:export']"        >导出        </el-button>      </el-col>      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>    </el-row>    <el-table border v-loading="loading" :data="courseFinishTempList" @selection-change="handleSelectionChange">      <el-table-column type="selection" width="55" align="center"/>      <el-table-column label="模板ID" align="center" prop="id"/>      <el-table-column label="模板名称" align="center" prop="name"/>      <el-table-column label="状态" align="center" prop="status">        <template slot-scope="scope">          <dict-tag :options="statusOptions" :value="scope.row.status"/>        </template>      </el-table-column>      <el-table-column label="课程名称" align="center" prop="courseName"/>      <el-table-column label="小节名称" align="center" prop="videoName"/>      <el-table-column label="创建时间" align="center" prop="createTime"/>      <el-table-column label="修改时间" align="center" prop="updateTime"/>      <el-table-column label="全选销售" align="center" prop="isAllCompanyUser">        <template slot-scope="scope">          <dict-tag :options="allowSelect" :value="scope.row.isAllCompanyUser"/>        </template>      </el-table-column>      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">        <template slot-scope="scope">          <el-button            size="mini"            type="text"            icon="el-icon-edit"            @click="handleUpdate(scope.row)"            v-hasPermi="['courseFinishTemp:course:edit']"          >修改          </el-button>          <el-button            size="mini"            type="text"            icon="el-icon-s-promotion"            @click="handleSelectDetails(scope.row)"            v-hasPermi="['courseFinishTemp:course:query']"          >详情          </el-button>          <el-button            size="mini"            type="text"            icon="el-icon-delete"            @click="handleDelete(scope.row)"            v-hasPermi="['courseFinishTemp:course:remove']"          >删除          </el-button>        </template>      </el-table-column>    </el-table>    <pagination      v-show="total>0"      :total="total"      :page.sync="queryParams.pageNum"      :limit.sync="queryParams.pageSize"      @pagination="getList"    />    <!-- 添加或修改完课模板对话框 -->    <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>      <el-form ref="form" :model="form" :rules="rules" label-width="80px">        <el-form-item label="模板名称" prop="name">          <el-input v-model="form.name" placeholder="请输入模板名称"/>        </el-form-item>        <el-form-item label="状态">          <el-radio-group v-model="form.status">            <el-radio              v-for="dict in statusOptions"              :key="dict.dictValue"              :label="parseInt(dict.dictValue)"            >{{ dict.dictLabel }}            </el-radio>          </el-radio-group>        </el-form-item>        <el-form-item label="选择课程">          <el-select v-model="form.courseId" placeholder="请选择课程" style=" margin-right: 10px;" size="mini"                     @change="courseChange()">            <el-option              v-for="dict in courseList"              :key="dict.dictValue"              :label="dict.dictLabel"              :value="parseInt(dict.dictValue)"            />          </el-select>          <el-select v-model="form.videoId" placeholder="请选择小节" size="mini" style=" margin-right: 10px;">            <el-option              v-for="dict in videoList"              :key="dict.dictValue"              :label="dict.dictLabel"              :value="parseInt(dict.dictValue)"            />          </el-select>        </el-form-item>        <el-form-item label="规则" prop="setting">          <div v-for="(item, index) in setting" :key="index"               style="background-color: #fdfdfd; border: 1px solid #e6e6e6; margin-bottom: 20px;">            <el-row>              <el-col :span="22">                <el-form :model="item" label-width="70px">                  <el-form-item label="内容类别" style="margin: 2%">                    <el-radio-group v-model="item.contentType">                      <el-radio :label="item.dictValue" v-for="item in sysQwSopAiContentType">{{ item.dictLabel }}                      </el-radio>                    </el-radio-group>                  </el-form-item>                  <el-form-item label="内容" style="margin-bottom: 2%">                    <el-input v-if="item.contentType == 1 " v-model="item.value" type="textarea" :rows="3"                              placeholder="内容" style="width: 90%;margin-top: 10px;"/>                    <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1" :width="150"                                 :height="150"/>                    <div v-if="item.contentType == 3 ">                      <el-card class="box-card">                        <el-form-item label="链接标题:" label-width="100px">                          <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>                        </el-form-item>                        <el-form-item label="链接描述:" label-width="100px">                          <el-input type="textarea" :rows="3" v-model="item.linkDescribe" placeholder="请输入链接描述"                                    style="width: 90%;margin-top: 1%;"/>                        </el-form-item>                        <el-form-item label="链接封面:" label-width="100px">                          <ImageUpload v-model="item.linkImageUrl" type="image" :num="1" :file-size="2" :width="150"                                       :height="150" style="margin-top: 1%;"/>                        </el-form-item>                        <el-form-item label="链接地址:" label-width="100px">                          <el-input v-model="item.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>                        </el-form-item>                      </el-card>                    </div>                    <div v-if="item.contentType == 4">                      <el-card class="box-card">                        <el-form-item label="选择课程">                          <el-select                            v-model="item.courseId"                            placeholder="请选择课程"                            style="margin-right: 10px"                            size="mini"                            @change="handleRuleCourseChange(item)"                          >                            <el-option                              v-for="dict in courseList"                              :key="dict.dictValue"                              :label="dict.dictLabel"                              :value="parseInt(dict.dictValue)"                            />                          </el-select>                          <el-select                            v-model="item.videoId"                            placeholder="请选择小节"                            size="mini"                            style="margin-right: 10px"                            filterable                            remote                            :remote-method="(query) => remoteMethodRuleVideo(query, item)"                            :loading="videoOptionsLoading"                            @change="handleRuleVideoChange(item)"                          >                            <el-option                              v-for="dict in videoOptions || []"                              :key="dict.dictValue"                              :label="dict.dictLabel"                              :value="parseInt(dict.dictValue)"                            />                          </el-select>                        </el-form-item>                        <el-card class="box-card" style="margin-top: 10px">                          <el-form-item label="标题" prop="miniprogramTitle">                            <el-input v-model="item.miniprogramTitle" placeholder="请输入小程序消息标题,最长为64字" />                          </el-form-item>                          <el-form-item label="封面" prop="miniprogramPicUrl">                            <ImageUpload v-model="item.miniprogramPicUrl" type="image" :num="10" :width="150" :height="150" />                          </el-form-item>                        </el-card>                      </el-card>                    </div>                    <div v-if="item.contentType == 5 ">                      <el-form-item label="上传文件:" prop="fileUrl" label-width="100px">                        <el-upload                          v-model="item.fileUrl"                          class="avatar-uploader"                          :action="uploadUrl"                          :show-file-list="false"                          :on-success="(res, file) => handleAvatarSuccessFile(res, file, item)"                          :before-upload="beforeAvatarUploadFile">                          <i class="el-icon-plus avatar-uploader-icon"></i>                        </el-upload>                        <el-link v-if="item.fileUrl" type="primary" :href="downloadUrl(item.fileUrl)" download>                          {{ item.fileUrl }}                        </el-link>                      </el-form-item>                    </div>                    <div v-if="item.contentType == 6 ">                      <el-form-item label="上传视频:" prop="videoUrl" label-width="100px">                        <el-upload                          v-model="item.videoUrl"                          class="avatar-uploader"                          :action="uploadUrl"                          :show-file-list="false"                          :on-success="(res, file) => handleAvatarSuccessVideo(res, file, item)"                          :before-upload="beforeAvatarUploadVideo">                          <i class="el-icon-plus avatar-uploader-icon"></i>                        </el-upload>                        <video v-if="item.videoUrl"                               :src="item.videoUrl"                               controls style="width: 200px;height: 100px">                        </video>                      </el-form-item>                    </div>                    <div v-if="item.contentType == 7 ">                      <el-input                        v-model="item.value"                        type="textarea" :rows="3" maxlength="66" show-word-limit                        placeholder="输入要转为语音的内容" style="width: 90%;margin-top: 10px;"                        @input="handleInputVideoText(item.value,item)"/>                    </div>                    <div v-if="item.contentType == 8">                      <el-button type="primary"                                 style="margin-bottom: 1%"                                 @click="hanldeSelectVideoNum(setting,index)">                        选择视频号                      </el-button>                      <el-card class="box-card" v-if="item.coverUrl">                        <el-form-item label="封面标题:" label-width="100px">                          <el-input v-model="item.nickname"                                    style="width: 90%;margin-bottom: 1%" disabled/>                        </el-form-item>                        <el-form-item label="头像:" label-width="100px">                          <el-image                            v-if="item.avatar != null"                            :src="item.avatar"                            :preview-src-list="[item.avatar]"                            :style="{ width: '50px', height: '50px' }"                          ></el-image>                        </el-form-item>                        <el-form-item label="封面:" label-width="100px">                          <el-image                            v-if="item.coverUrl != null"                            :src="item.coverUrl"                            :preview-src-list="[item.coverUrl]"                            :style="{ width: '200px', height: '200px' }"                          ></el-image>                        </el-form-item>                        <el-form-item label="简介:" label-width="100px">                          <el-input type="textarea" :rows="3"                                    v-model="item.desc"                                    style="width: 90%;margin-top: 1%;" disabled/>                        </el-form-item>                        <el-form-item label="视频地址:" label-width="100px"                                      style="margin-top: 1%">                          <el-input v-model="item.url"                                    style="width: 90%;" disabled/>                        </el-form-item>                      </el-card>                    </div>                  </el-form-item>                </el-form>              </el-col>              <el-col :span="1" :offset="1">                <i class="el-icon-delete" @click="delSetList(index, 0)" style="margin-top: 20px;"                   v-if="setting.length>1 && formType==1"></i>              </el-col>            </el-row>          </div>          <el-link type="primary" class="el-icon-plus" :underline="false" @click='addSetList(0)' v-if="formType==1">            添加内容          </el-link>        </el-form-item>        <el-form-item label="群聊恭喜规则" prop="setting">          <div v-for="(item, index) in chatSetting" :key="index"               style="background-color: #fdfdfd; border: 1px solid #e6e6e6; margin-bottom: 20px;">            <el-row>              <el-col :span="22">                <el-form :model="item" label-width="70px">                  <el-form-item label="内容类别" style="margin: 2%">                    <el-radio-group v-model="item.contentType">                      <el-radio :label="item.dictValue" v-for="item in sysQwSopAiContentType">{{ item.dictLabel }}                      </el-radio>                    </el-radio-group>                  </el-form-item>                  <el-form-item label="内容" style="margin-bottom: 2%">                    <el-input v-if="item.contentType == 1 " v-model="item.value" type="textarea" :rows="3"                              placeholder="内容" style="width: 90%;margin-top: 10px;"/>                    <ImageUpload v-if="item.contentType == 2 " v-model="item.imgUrl" type="image" :num="1" :width="150"                                 :height="150"/>                    <div v-if="item.contentType == 3 ">                      <el-card class="box-card">                        <el-form-item label="链接标题:" label-width="100px">                          <el-input v-model="item.linkTitle" placeholder="请输入链接标题" style="width: 90%;"/>                        </el-form-item>                        <el-form-item label="链接描述:" label-width="100px">                          <el-input type="textarea" :rows="3" v-model="item.linkDescribe" placeholder="请输入链接描述"                                    style="width: 90%;margin-top: 1%;"/>                        </el-form-item>                        <el-form-item label="链接封面:" label-width="100px">                          <ImageUpload v-model="item.linkImageUrl" type="image" :num="1" :file-size="2" :width="150"                                       :height="150" style="margin-top: 1%;"/>                        </el-form-item>                        <el-form-item label="链接地址:" label-width="100px">                          <el-input v-model="item.linkUrl" placeholder="请输入链接地址" style="width: 90%;"/>                        </el-form-item>                      </el-card>                    </div>                    <div v-if="item.contentType == 4">                      <el-card class="box-card">                        <el-form-item label="选择课程">                          <el-select                            v-model="item.courseId"                            placeholder="请选择课程"                            style="margin-right: 10px"                            size="mini"                            @change="handleRuleCourseChange(item)"                          >                            <el-option                              v-for="dict in courseList"                              :key="dict.dictValue"                              :label="dict.dictLabel"                              :value="parseInt(dict.dictValue)"                            />                          </el-select>                          <el-select                            v-model="item.videoId"                            placeholder="请选择小节"                            size="mini"                            style="margin-right: 10px"                            filterable                            remote                            :remote-method="(query) => remoteMethodRuleVideo(query, item)"                            :loading="videoOptionsLoading"                            @change="handleRuleVideoChange(item)"                          >                            <el-option                              v-for="dict in videoOptions || []"                              :key="dict.dictValue"                              :label="dict.dictLabel"                              :value="parseInt(dict.dictValue)"                            />                          </el-select>                        </el-form-item>                        <el-card class="box-card" style="margin-top: 10px">                          <el-form-item label="标题" prop="miniprogramTitle">                            <el-input v-model="item.miniprogramTitle" placeholder="请输入小程序消息标题,最长为64字" />                          </el-form-item>                          <el-form-item label="封面" prop="miniprogramPicUrl">                            <ImageUpload v-model="item.miniprogramPicUrl" type="image" :num="10" :width="150" :height="150" />                          </el-form-item>                        </el-card>                      </el-card>                    </div>                    <div v-if="item.contentType == 5 ">                      <el-form-item label="上传文件:" prop="fileUrl" label-width="100px">                        <el-upload                          v-model="item.fileUrl"                          class="avatar-uploader"                          :action="uploadUrl"                          :show-file-list="false"                          :on-success="(res, file) => handleAvatarSuccessFile(res, file, item)"                          :before-upload="beforeAvatarUploadFile">                          <i class="el-icon-plus avatar-uploader-icon"></i>                        </el-upload>                        <el-link v-if="item.fileUrl" type="primary" :href="downloadUrl(item.fileUrl)" download>                          {{ item.fileUrl }}                        </el-link>                      </el-form-item>                    </div>                    <div v-if="item.contentType == 6 ">                      <el-form-item label="上传视频:" prop="videoUrl" label-width="100px">                        <el-upload                          v-model="item.videoUrl"                          class="avatar-uploader"                          :action="uploadUrl"                          :show-file-list="false"                          :on-success="(res, file) => handleAvatarSuccessVideo(res, file, item)"                          :before-upload="beforeAvatarUploadVideo">                          <i class="el-icon-plus avatar-uploader-icon"></i>                        </el-upload>                        <video v-if="item.videoUrl"                               :src="item.videoUrl"                               controls style="width: 200px;height: 100px">                        </video>                      </el-form-item>                    </div>                    <div v-if="item.contentType == 7 ">                      <el-input                        v-model="item.value"                        type="textarea" :rows="3" maxlength="66" show-word-limit                        placeholder="输入要转为语音的内容" style="width: 90%;margin-top: 10px;"                        @input="handleInputVideoText(item.value,item)"/>                    </div>                    <div v-if="item.contentType == 8">                      <el-button type="primary"                                 style="margin-bottom: 1%"                                 @click="hanldeSelectVideoNum(setting,index)">                        选择视频号                      </el-button>                      <el-card class="box-card" v-if="item.coverUrl">                        <el-form-item label="封面标题:" label-width="100px">                          <el-input v-model="item.nickname"                                    style="width: 90%;margin-bottom: 1%" disabled/>                        </el-form-item>                        <el-form-item label="头像:" label-width="100px">                          <el-image                            v-if="item.avatar != null"                            :src="item.avatar"                            :preview-src-list="[item.avatar]"                            :style="{ width: '50px', height: '50px' }"                          ></el-image>                        </el-form-item>                        <el-form-item label="封面:" label-width="100px">                          <el-image                            v-if="item.coverUrl != null"                            :src="item.coverUrl"                            :preview-src-list="[item.coverUrl]"                            :style="{ width: '200px', height: '200px' }"                          ></el-image>                        </el-form-item>                        <el-form-item label="简介:" label-width="100px">                          <el-input type="textarea" :rows="3"                                    v-model="item.desc"                                    style="width: 90%;margin-top: 1%;" disabled/>                        </el-form-item>                        <el-form-item label="视频地址:" label-width="100px"                                      style="margin-top: 1%">                          <el-input v-model="item.url"                                    style="width: 90%;" disabled/>                        </el-form-item>                      </el-card>                    </div>                  </el-form-item>                </el-form>              </el-col>              <el-col :span="1" :offset="1">                <i class="el-icon-delete" @click="delSetList(index,1)" style="margin-top: 20px;"                   v-if="setting.length>1 && formType==1"></i>              </el-col>            </el-row>          </div>          <el-link type="primary" class="el-icon-plus" :underline="false" @click='addSetList(1)' v-if="formType==1">            添加内容          </el-link>        </el-form-item>        <el-form-item label="全选销售" prop="isAllCompanyUser">          <el-switch            v-model="form.isAllCompanyUser"            active-color="#13ce66"            inactive-color="#ff4949"            :active-value="1"            :inactive-value="2">          </el-switch>          <span v-if="form.isAllCompanyUser == '1'" style="margin-left: 10px;color: #13ce66">是</span>          <span v-else style="margin-left: 10px;color: #ff4949">否</span>          <Tip :title="'是否 全选整个销售公司的销售,作用于这个课程小节,当这个小节有客户完课时,发送此设置的内容'" />        </el-form-item>        <el-form-item label="所属销售" prop="companyUserIds" v-if="form.isAllCompanyUser == '2'">          <el-select v-model="companyUserIds" remote multiple placeholder="请选择" filterable style="width: 100%;">            <el-option              v-for="dict in userList"              :key="dict.userId"              :label="dict.nickName"              :value="dict.userId.toString()">            </el-option>          </el-select>        </el-form-item>      </el-form>      <div slot="footer" class="dialog-footer" v-if="formType==1">        <el-button type="primary" @click="submitForm">确 定</el-button>        <el-button @click="cancel">取 消</el-button>      </div>    </el-dialog>    <el-dialog title="批量修改状态" :visible.sync="batchOpen" width="400px" append-to-body>      <el-form ref="form" :model="statusForm">         <el-form-item label="状态">          <el-radio-group v-model="statusForm.status">            <el-radio              v-for="dict in statusOptions"              :key="dict.dictValue"              :label="parseInt(dict.dictValue)"            >{{ dict.dictLabel }}            </el-radio>          </el-radio-group>        </el-form-item>      </el-form>      <div slot="footer" class="dialog-footer" v-if="formType==1">        <el-button type="primary" @click="submitFormBatchStatus" :loading="submitFormBatchStatusLoading">确 定</el-button>        <el-button @click="batchOpen = false">取 消</el-button>      </div>    </el-dialog>    <el-dialog :title="videoNumOptions.title" :visible.sync="videoNumOptions.open" width="1500px" append-to-body>      <userVideo ref="QwUserVideo" @videoResult="qwUserVideoResult"></userVideo>    </el-dialog>  </div></template><script>import {  addCourseFinishTemp,  delCourseFinishTemp,  exportCourseFinishTemp,  getCourseFinishTemp,  listCourseFinishTemp,  updateCourseFinishTemp,  updateStatusBatch} from '@/api/course/courseFinishTemp'import { getUserList } from '@/api/company/companyUser'import { courseList, videoList } from '@/api/qw/sop'import ImageUpload from '@/views/qw/sop/ImageUpload.vue'import Tip from "../../../components/Tip/index.vue";import userVideo from "@/views/qw/userVideo/userVideo.vue";export default {  name: "CourseFinishTemp",  components: {Tip, ImageUpload,userVideo},  data() {    return {      videoOptionsLoading: false,      videoOptions: [],      videoLoading: false,      videoNumOptions: {        title: '选择视频号',        open: false,        content: null,        contentIndex: null,      },      //上传语音的遮罩层      voiceLoading: false,      uploadUrl: process.env.VUE_APP_BASE_API + "/common/uploadOSS2",      uploadUrlByVoice: process.env.VUE_APP_BASE_API + "/common/uploadOSSByHOOKVoice",      companyUserIds: [],      userList: [],      // 状态字典      statusOptions: [],      allowSelect: [],      courseList: [],      videoList: [],      // 遮罩层      loading: true,      // 导出遮罩层      exportLoading: false,      // 选中数组      ids: [],      // 非单个禁用      single: true,      // 非多个禁用      multiple: true,      // 显示搜索条件      showSearch: true,      formType: 1,      // 总条数      total: 0,      // 完课模板表格数据      courseFinishTempList: [],      //插件版      sysQwSopAiContentType: [],      sysFsSopWatchStatus: [],      // 弹出层标题      title: "",      // 是否显示弹出层      open: false,      batchOpen:false,      submitFormBatchStatusLoading:false,      // 查询参数      queryParams: {        pageNum: 1,        pageSize: 10,        name: null,        status: null,        setting: null,        chatSetting: null,        companyId: null,        courseId: null,        videoId: null,        companyUserIds: null,        isDel: null      },      // 模板表格数据      setting: [],      parentId: "",      chatSetting: [],      // 表单参数      form: {        companyUserIds: [],        setting: null,        chatSetting: null,        videoIdSet: null,        courseIdSet: null,      },      statusForm:{        status:null      },      // 表单校验      rules: {}    };  },  created() {    this.queryParams.parentId = this.$route.params && this.$route.params.parentId;    this.parentId = this.queryParams.parentId;    getUserList().then(response => {      this.userList = response.data;      console.log("this.userList", this.userList)    });    this.getDicts("sys_company_status").then(response => {      this.statusOptions = response.data;    });    //复用一下    this.getDicts("sys_qw_allow_select").then(response => {      this.allowSelect = response.data;    });    this.getDicts("sys_fs_sop_watch_status").then(response => {      this.sysFsSopWatchStatus = response.data;    });    this.getDicts("sys_qwSopAi_contentType").then(response => {      this.sysQwSopAiContentType = response.data;    });    courseList().then(response => {      this.courseList = response.list;    });    this.getList();  },  methods: {    // 处理规则中课程变化    handleRuleCourseChange(item) {      // 为当前规则项单独加载视频列表      videoList(item.courseId).then((response) => {        // 只保存视频列表,不保存整个响应对象        this.videoOptions = response.list;        this.$set(item, 'videoId', null); // Reset video selection when course changes        // 自动设置封面为课程封面        const selectedCourse = this.courseList.find(          course => parseInt(course.dictValue) === item.courseId        );        if (selectedCourse) {          this.$set(item, 'miniprogramPicUrl', selectedCourse.dictImgUrl);        }      });    },    // 处理规则中视频变化    handleRuleVideoChange(item) {      if (!item.videoId) return;      // 自动设置标题为视频标题      const selectedVideo = (this.videoOptions || []).find(        video => parseInt(video.dictValue) === item.videoId      );      if (selectedVideo) {        this.$set(item, 'miniprogramTitle', selectedVideo.dictLabel);      }    },    // 远程搜索规则中的视频    remoteMethodRuleVideo(query, item) {      if (!item.courseId) {        this.$message.warning('请先选择课程');        this.videoOptions = [];        reject();        return;      }      this.videoOptionsLoading = true;      const data = query ? { title: query } : {};      videoList(item.courseId, data).then((response) => {        this.videoOptions =  response.list;        this.videoOptionsLoading =  false;        resolve(response);      }).catch((error) => {        this.videoOptionsLoading = false;        reject(error);      });    },    remoteMethodVideo(query) {      if (!this.form.courseId) {        this.$message.warning('请先选择课程');        this.videoList = []; // 清空小节列表        return;      }      if (query !== '') {        this.videoLoading = true;        // 这里调用接口搜索小节,假设 videoList 方法支持搜索参数        var data = {          title:query        }        videoList(this.form.courseId, data).then((response) => {          this.videoList = response.list;          this.videoLoading = false;        });      } else {        // 如果查询为空,则加载全部        videoList(this.form.courseId).then((response) => {          this.videoList = response.list;        });      }    },    qwUserVideoResult(val) {      // 根据选中的内容,将返回的数据更新到相应的表单项      const content = this.videoNumOptions.content;      const setList = content[this.videoNumOptions.contentIndex];      setList.nickname = val.nickname;      setList.avatar = val.avatar;      setList.coverUrl = val.coverUrl;      setList.thumbUrl = val.thumbUrl;      setList.desc = val.desc;      setList.url = val.url;      setList.extras = val.extras;      setList.videoId = val.id;      console.info(setList)      this.videoNumOptions.open = false;    },    courseChange() {      videoList(this.form.courseId).then(response => {        this.videoList = response.list;      });    },    /** 查询完课模板列表 */    getList() {      this.loading = true;      listCourseFinishTemp(this.queryParams).then(response => {        this.courseFinishTempList = response.rows;        this.total = response.total;        this.loading = false;      });    },    // 取消按钮    cancel() {      this.open = false;      this.reset();    },    handleAvatarSuccessFile(res, file, item) {      if (res.code === 200) {        // 使用 $set 确保响应式更新        this.$set(item, 'fileUrl', res.url);      } else {        this.msgError(res.msg);      }    },    beforeAvatarUploadFile(file) {      const isLt1M = file.size / 1024 / 1024 < 10;      if (!isLt1M) {        this.$message.error('上传大小不能超过 10MB!');      }      return isLt1M;    },    //下载文件    downloadUrl(materialUrl) {      // 直接返回文件 URL      return materialUrl;    },    handleInputVideoText(value, content) {      // 允许的字符:中文、英文(大小写)、数字和指定标点符号(,。!?)      const regex = /^[\u4e00-\u9fa5,。!?,!?]+$/;      // 删除不符合条件的字符      const filteredValue = value.split('').filter(char => regex.test(char)).join('');      this.$set(content, 'value', filteredValue);    },    handleAvatarSuccessVideo(res, file, item) {      if (res.code == 200) {        // 使用 $set 确保响应式更新        this.$set(item, 'videoUrl', res.url);      } else {        this.msgError(res.msg);      }    },    beforeAvatarUploadVideo(file) {      const isLt30M = file.size / 1024 / 1024 < 10;      const isMP4 = file.type === 'video/mp4';      if (!isMP4) {        this.$message.error('仅支持上传 MP4 格式的视频文件!');        return false;      }      if (!isLt30M) {        this.$message.error('上传大小不能超过 10MB!');        return false;      }      return true;    },    delSetList(index, type) {      if (type == 0) {        this.setting.splice(index, 1)      } else {        this.chatSetting.splice(index, 1)      }    },    addSetList(type) {      const newSetting = {        contentType: '1',        value: '',      };      // 将新设置项添加到 content.setting 数组中      if (type == 0) {        this.setting.push(newSetting);      } else {        this.chatSetting.push(newSetting);      }    },    // 表单重置    reset() {      this.form = {        id: null,        name: null,        type: 1,        status: 1,        setting: [],        chatSetting: [],        companyId: null,        createBy: null,        createTime: null,        courseId: null,        videoId: null,        companyUserIds: null,        updateTime: null,        isDel: null,        isAllCompanyUser: null,      };      this.companyUserIds = []      this.setting = []      this.chatSetting = []      this.resetForm("form");      this.formType = 1    },    /** 搜索按钮操作 */    handleQuery() {      this.queryParams.pageNum = 1;      this.getList();    },    /** 重置按钮操作 */    resetQuery() {      this.resetForm("queryForm");      this.handleQuery();    },    // 多选框选中数据    handleSelectionChange(selection) {      this.ids = selection.map(item => item.id)      this.single = selection.length !== 1      this.multiple = !selection.length    },    /** 新增按钮操作 */    handleAdd() {      this.reset();      this.open = true;      this.title = "添加完课模板";    },    //选择视频号    hanldeSelectVideoNum(content, index) {      this.videoNumOptions.content = content;      this.videoNumOptions.contentIndex = index;      this.videoNumOptions.open = true;    },    /**     * 查看完课模板     */    handleSelectDetails(row) {      this.reset();      const id = row.id || this.ids      getCourseFinishTemp(id).then(response => {        console.log("this.form222 ", response.data)        this.form = response.data;        this.setting = JSON.parse(this.form.setting)        this.chatSetting = JSON.parse(this.form.chatSetting)        if (response.data.companyUserIds != null) {          this.companyUserIds = this.form.companyUserIds.split(",");        }        videoList(this.form.courseId).then(response => {          this.videoList = response.list;        });        this.open = true;        this.title = "查看完课模板";        this.formType = 2;      });    },    // 批量修改状态    handleUpdateStatusBatch(){      console.log(this.ids);      if(this.ids == null || this.ids == undefined || this.ids.length == 0 ){        return this.$message.error("请选择数据")      }      this.statusForm.status = null;      this.batchOpen = true;    },    /** 修改按钮操作 */    handleUpdate(row) {      this.reset();      const id = row.id || this.ids      getCourseFinishTemp(id).then(response => {        console.log("this.response.data", response.data)        this.form = response.data;        this.setting = JSON.parse(this.form.setting)        this.chatSetting = JSON.parse(this.form.chatSetting)        if (response.data.companyUserIds != null) {          this.companyUserIds = this.form.companyUserIds.split(",");        }        videoList(this.form.courseId).then(response => {          this.videoList = response.list;        });        this.setting.forEach(item => {          if (item.contentType == 4 && item.courseId) {            // 初始化 videoOptions            this.videoOptions = [];            this.videoOptionsLoading = false;            // 获取课程对应的小节列表            videoList(item.courseId).then((videoResponse) => {              this.videoOptions = videoResponse.list;            });          }        });        this.open = true;        this.title = "修改完课模板";        this.formType = 1;      });    },    submitFormBatchStatus(){      if(this.statusForm.status==null){        return this.$message.error("状态不能为空,请选择状态")      }      if(this.ids == null || this.ids == undefined || this.ids.length == 0 ){        return this.$message.error("请选择数据")      }      let _this = this;      _this.submitFormBatchStatusLoading = true;      let param ={        ids:_this.ids,        status:_this.statusForm.status      }      updateStatusBatch(param).then(res=>{        _this.submitFormBatchStatusLoading = false;        _this.msgSuccess("修改成功");        _this.batchOpen = false;        _this.getList();      }).catch(res=>{        console.log(res);        _this.submitFormBatchStatusLoading = false;      })    },    /** 提交按钮 */    submitForm() {      this.$refs["form"].validate(valid => {        if (valid) {          if (this.form.isAllCompanyUser == null) {            this.form.isAllCompanyUser = 2;          }          this.form.companyUserIds = this.companyUserIds.toString()          this.form.parentId = this.parentId          const processedSetting = this.setting.map(item => {            const newItem = {...item};            if (newItem.videoOptions) {              delete newItem.videoOptions;            }            if (newItem.videoLoading !== undefined) {              delete newItem.videoLoading;            }            return newItem;          });          this.form.setting = JSON.stringify(processedSetting);          this.form.chatSetting = JSON.stringify(this.chatSetting)          if (this.setting.length <= 0) {            return this.$message("请添加规则")          }          for (let i = 0; i < this.setting.length; i++) {            if (this.setting[i].contentType == 1 && (this.setting[i].value == null || this.setting[i].value == "")) {              return this.$message.error("内容不能为空")            }            if (this.setting[i].contentType == 2 && (this.setting[i].imgUrl == null || this.setting[i].imgUrl == "")) {              return this.$message.error("图片不能为空")            }            if (this.setting[i].contentType == 3 && (this.setting[i].linkTitle == null || this.setting[i].linkTitle == "")) {              return this.$message.error("链接标题不能为空")            }            if (this.setting[i].contentType == 3 && (this.setting[i].linkDescribe == null || this.setting[i].linkDescribe == "")) {              return this.$message.error("链接描述不能为空")            }            if (this.setting[i].contentType == 3 && (this.setting[i].linkImageUrl == null || this.setting[i].linkImageUrl == "")) {              return this.$message.error("链接图片不能为空")            }            if (this.setting[i].contentType == 3 && this.setting[i].type == 1 && (this.setting[i].linkUrl == null || this.setting[i].linkUrl == "")) {              return this.$message.error("链接地址不能为空")            }            if (this.setting[i].contentType == 5 && (this.setting[i].fileUrl == null || this.setting[i].fileUrl == "")) {              return this.$message.error("文件不能为空")            }            if (this.setting[i].contentType == 6 && (this.setting[i].videoUrl == null || this.setting[i].videoUrl == "")) {              return this.$message.error("视频不能为空")            }            if (this.setting[i].contentType == 7 && (this.setting[i].value == null || this.setting[i].value == "")) {              return this.$message.error("语音不能为空")            }          }          if (this.form.id != null) {            updateCourseFinishTemp(this.form).then(response => {              this.msgSuccess("修改成功");              this.open = false;              this.getList();              this.setting = [];              this.chatSetting = [];            });          } else {            addCourseFinishTemp(this.form).then(response => {              this.msgSuccess("新增成功");              this.open = false;              this.setting = [];              this.chatSetting = [];              this.getList();            });          }        }      });    },    /** 删除按钮操作 */    handleDelete(row) {      const ids = row.id || this.ids;      this.$confirm('是否确认删除完课模板编号为"' + ids + '"的数据项?', "警告", {        confirmButtonText: "确定",        cancelButtonText: "取消",        type: "warning"      }).then(function () {        return delCourseFinishTemp(ids);      }).then(() => {        this.getList();        this.msgSuccess("删除成功");      }).catch(() => {      });    },    /** 导出按钮操作 */    handleExport() {      const queryParams = this.queryParams;      this.$confirm('是否确认导出所有完课模板数据项?', "警告", {        confirmButtonText: "确定",        cancelButtonText: "取消",        type: "warning"      }).then(() => {        this.exportLoading = true;        return exportCourseFinishTemp(queryParams);      }).then(response => {        this.download(response.msg);        this.exportLoading = false;      }).catch(() => {      });    }  }};</script>
 |